contaigents
Version:
Modular AI Content Ecosystem with Audio Generation
218 lines (217 loc) โข 8.85 kB
JavaScript
/**
* TextToImageTool Tailwind Guardrails Test
*
* This script tests the Tailwind-only guardrails functionality:
* 1. Ensures generated HTML uses only Tailwind CSS classes
* 2. Validates that raw CSS is stripped from generated content
* 3. Tests the AI prompt guardrails
* 4. Verifies fallback template uses only Tailwind
*/
import { ToolManager } from '../services/tools/ToolManager.js';
import { BrowserServiceManager } from '../services/tools/BrowserService.js';
import fs from 'fs/promises';
import path from 'path';
import { fileURLToPath } from 'url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
// Test configuration
const TEST_BASE_DIR = path.join(__dirname, 'test_tailwind_guardrails_output');
class TailwindGuardrailsTest {
constructor() {
this.toolManager = new ToolManager(TEST_BASE_DIR);
}
async setup() {
console.log('๐ง Setting up Tailwind guardrails test environment...');
// Create test output directory
await fs.mkdir(TEST_BASE_DIR, { recursive: true });
console.log(`๐ Test directory: ${TEST_BASE_DIR}`);
console.log('');
}
async cleanup() {
console.log('๐งน Cleaning up...');
// Close browser service
await BrowserServiceManager.cleanup();
console.log('โ
Cleanup completed');
}
async testTailwindOnlyGeneration() {
console.log('๐จ Test 1: Tailwind-Only Generation');
console.log('-'.repeat(35));
const toolCall = {
tool_name: 'text_to_image',
parameters: {
text: 'Modern Design with Tailwind CSS',
output_path: 'tailwind_test.png',
design_prompt: 'Modern minimalist card with blue gradient background and white text, using only Tailwind CSS classes',
width: 800,
height: 600
}
};
console.log('๐ Tool Call Parameters:');
console.log(JSON.stringify(toolCall.parameters, null, 2));
console.log('');
const result = await this.toolManager.executeTool(toolCall);
if (result.success) {
console.log('โ
Tailwind-only generation successful!');
console.log('๐ Result data:', JSON.stringify(result.data, null, 2));
// Check the generated HTML file for Tailwind compliance
const htmlPath = path.join(TEST_BASE_DIR, 'tailwind_test.html');
await this.validateTailwindCompliance(htmlPath);
}
else {
console.log('โ Tailwind-only generation failed:', result.error);
}
console.log('');
}
async testRawCSSRemoval() {
console.log('๐ซ Test 2: Raw CSS Removal');
console.log('-'.repeat(26));
// Create an HTML file with raw CSS to test the guardrails
const htmlWithRawCSS = `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Test with Raw CSS</title>
<script src="https://cdn.tailwindcss.com"></script>
<style>
.custom-style {
background: linear-gradient(45deg, red, blue);
color: white;
padding: 20px;
}
</style>
</head>
<body class="m-0 p-0" style="width: 800px; height: 600px; background-color: yellow;">
<div class="custom-style" style="font-size: 24px;">
This should be cleaned up!
</div>
</body>
</html>`;
const testHtmlPath = path.join(TEST_BASE_DIR, 'raw_css_test.html');
await fs.writeFile(testHtmlPath, htmlWithRawCSS, 'utf-8');
const toolCall = {
tool_name: 'text_to_image',
parameters: {
html_file_path: 'raw_css_test.html',
output_path: 'cleaned_test.png',
html_only: true,
width: 800,
height: 600
}
};
const result = await this.toolManager.executeTool(toolCall);
if (result.success) {
console.log('โ
Raw CSS removal test completed!');
// The tool should have processed the HTML and removed raw CSS
// Let's check if a new cleaned HTML was generated
console.log('๐ File generated:', result.data.output_file_path);
}
else {
console.log('โ Raw CSS removal test failed:', result.error);
}
console.log('');
}
async testFallbackTemplate() {
console.log('๐ Test 3: Fallback Template Tailwind Compliance');
console.log('-'.repeat(45));
// Test with a design prompt that might trigger the fallback template
const toolCall = {
tool_name: 'text_to_image',
parameters: {
text: 'Fallback Template Test',
output_path: 'fallback_test.png',
design_prompt: 'Blue gradient background with shadow effects',
width: 600,
height: 400
}
};
const result = await this.toolManager.executeTool(toolCall);
if (result.success) {
console.log('โ
Fallback template test successful!');
// Check the generated HTML file for Tailwind compliance
const htmlPath = path.join(TEST_BASE_DIR, 'fallback_test.html');
await this.validateTailwindCompliance(htmlPath);
}
else {
console.log('โ Fallback template test failed:', result.error);
}
console.log('');
}
async validateTailwindCompliance(htmlPath) {
try {
const htmlContent = await fs.readFile(htmlPath, 'utf-8');
console.log('๐ Validating Tailwind compliance...');
// Check for raw CSS violations
const hasStyleTags = /<style[^>]*>.*?<\/style>/gis.test(htmlContent);
const hasInlineStyles = /style="[^"]*(?:color|background|font-size|padding|margin)[^"]*"/gi.test(htmlContent);
// Allow body dimensions as they're necessary
const bodyDimensionPattern = /style="[^"]*(?:width|height):[^"]*"/gi;
const bodyDimensions = htmlContent.match(bodyDimensionPattern);
const hasOnlyBodyDimensions = bodyDimensions && bodyDimensions.length === 1 &&
bodyDimensions[0].includes('width:') && bodyDimensions[0].includes('height:');
if (hasStyleTags) {
console.log('โ Found <style> tags (should be removed by guardrails)');
}
else {
console.log('โ
No <style> tags found');
}
if (hasInlineStyles && !hasOnlyBodyDimensions) {
console.log('โ Found inline styles (should be removed by guardrails)');
}
else {
console.log('โ
No problematic inline styles found');
}
// Check for Tailwind CDN
const hasTailwindCDN = htmlContent.includes('tailwindcss.com');
if (hasTailwindCDN) {
console.log('โ
Tailwind CSS CDN included');
}
else {
console.log('โ Tailwind CSS CDN missing');
}
// Check for common Tailwind classes
const tailwindClasses = ['bg-', 'text-', 'p-', 'm-', 'flex', 'items-', 'justify-'];
const hasTailwindClasses = tailwindClasses.some(cls => htmlContent.includes(cls));
if (hasTailwindClasses) {
console.log('โ
Tailwind utility classes found');
}
else {
console.log('โ No Tailwind utility classes found');
}
}
catch (error) {
console.log('โ Failed to validate HTML file:', error.message);
}
}
async runAllTests() {
try {
await this.setup();
await this.testTailwindOnlyGeneration();
await this.testRawCSSRemoval();
await this.testFallbackTemplate();
await this.cleanup();
console.log('๐ All Tailwind guardrails tests completed!');
console.log('');
console.log('๐ Generated test files are available in:');
console.log(` ${TEST_BASE_DIR}`);
}
catch (error) {
console.error('โ Test failed:', error);
await this.cleanup();
process.exit(1);
}
}
}
// Run the tests
async function runTests() {
console.log('๐ Starting Tailwind Guardrails Tests');
console.log('');
const test = new TailwindGuardrailsTest();
await test.runAllTests();
}
// Execute if run directly
if (import.meta.url === `file://${process.argv[1]}`) {
runTests().catch(console.error);
}
export { TailwindGuardrailsTest };