UNPKG

testgenius-ai

Version:

๐Ÿš€ TestGenius AI - The Ultimate E2E Testing Framework for Everyone | No Coding Required โ€ข AI-Powered Automation โ€ข Beautiful Reports โ€ข Zero Complexity

181 lines โ€ข 6.76 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.SmartElementDetector = void 0; const chalk_1 = __importDefault(require("chalk")); class SmartElementDetector { constructor(browser) { this.browser = null; this.cache = new Map(); this.pageContext = {}; this.browser = browser; } /** * ๐Ÿš€ Fast element detection with multiple strategies */ async detectElement(description, elementType) { if (!this.browser) throw new Error('Browser not initialized'); // Check cache first const cacheKey = `${description}_${elementType || 'any'}`; if (this.cache.has(cacheKey)) { const cached = this.cache.get(cacheKey); console.log(chalk_1.default.gray(`โšก Using cached element: ${cached.strategy}`)); return cached; } console.log(chalk_1.default.blue(`๐Ÿ” Detecting element: ${description}`)); // Generate strategies based on description and type const strategies = this.generateStrategies(description, elementType); // Try each strategy in priority order for (const strategy of strategies) { try { const result = await this.tryStrategy(strategy, description); if (result) { // Cache the result this.cache.set(cacheKey, result); console.log(chalk_1.default.green(`โœ… Found element using: ${strategy.name} (${result.confidence}% confidence)`)); return result; } } catch (error) { console.log(chalk_1.default.yellow(`โš ๏ธ Strategy failed: ${strategy.name}`)); continue; } } console.log(chalk_1.default.red(`โŒ No element found for: ${description}`)); return null; } /** * ๐ŸŽฏ Generate detection strategies (Fast, no AI) */ generateStrategies(description, elementType) { const words = description.split(' ').filter(word => word.length > 2); const descriptionLower = description.toLowerCase(); const strategies = []; // Strategy 1: Accessibility Name (Highest Priority) strategies.push({ name: 'Accessibility Name', priority: 1, selectors: words.map(word => `aria/${word}`), description: 'Best practice - accessibility focused' }); // Strategy 2: Text-based (User-centric) strategies.push({ name: 'Text-based', priority: 2, selectors: [ ...words.map(word => `${word}`), ...words.map(word => `*=${word}`), ...words.map(word => `.*=${word}`) ], description: 'User-centric text matching' }); // Strategy 3: Element-specific text if (elementType) { strategies.push({ name: `${elementType} Text`, priority: 3, selectors: words.map(word => `${elementType}=${word}`), description: `Element-specific text matching for ${elementType}` }); } // Strategy 4: Data attributes strategies.push({ name: 'Data Attributes', priority: 4, selectors: words.map(word => `[data-testid*="${word}"]`), description: 'Test-specific attributes' }); // Strategy 5: ARIA attributes strategies.push({ name: 'ARIA Attributes', priority: 5, selectors: words.map(word => `[aria-label*="${word}"]`), description: 'Accessibility attributes' }); // Strategy 6: Common patterns if (descriptionLower.includes('button')) { strategies.push({ name: 'Button Patterns', priority: 6, selectors: ['button', '[role="button"]', '.btn', '.button'], description: 'Common button patterns' }); } if (descriptionLower.includes('input') || descriptionLower.includes('field')) { strategies.push({ name: 'Input Patterns', priority: 6, selectors: ['input', 'textarea', 'select'], description: 'Common input patterns' }); } // Strategy 7: Generic fallback strategies.push({ name: 'Generic Fallback', priority: 7, selectors: ['button', 'input', 'a', '[role="button"]'], description: 'Generic element types' }); return strategies.sort((a, b) => a.priority - b.priority); } /** * โšก Try a specific strategy */ async tryStrategy(strategy, description) { for (const selector of strategy.selectors) { try { const element = await this.browser.$(selector); if (element && await element.isExisting()) { const confidence = this.calculateConfidence(strategy, selector, description); return { element, confidence, strategy: strategy.name, selector }; } } catch (error) { continue; } } return null; } /** * ๐Ÿ“Š Calculate confidence score */ calculateConfidence(strategy, selector, description) { let confidence = 100; // Reduce confidence based on strategy priority confidence -= (strategy.priority - 1) * 10; // Boost confidence for exact matches const words = description.split(' ').filter(word => word.length > 2); const exactMatches = words.filter(word => selector.includes(word)).length; confidence += exactMatches * 5; // Reduce confidence for generic selectors if (selector === 'button' || selector === 'input' || selector === 'a') { confidence -= 20; } return Math.max(0, Math.min(100, confidence)); } /** * ๐Ÿงน Clear cache */ clearCache() { this.cache.clear(); } /** * ๐Ÿ“ˆ Get cache statistics */ getCacheStats() { return { size: this.cache.size, hitRate: 0 // TODO: Implement hit rate tracking }; } } exports.SmartElementDetector = SmartElementDetector; //# sourceMappingURL=SmartElementDetector.js.map