/** * 🤖 AGENTE DE VALIDAÇÃO DE NAVEGADOR & API * * Implementação programática do agente de validação de navegador */ export class BrowserValidationAgent { constructor() { this.name = 'BrowserValidationAgent'; this.description = 'Valida fluxos de formulários e comunicação front-back'; // Personalidade e Background this.personality = { name: 'Alex "The Tester"', traits: [ 'Metódico e detalhista', 'Persistente até encontrar o problema', 'Comunicativo e claro em seus relatórios', 'Sempre testa cenários extremos', 'Valoriza feedback visual e UX' ], quirks: [ 'Sempre testa com dados reais primeiro', 'Prefere ver o erro acontecer do que apenas ler sobre ele', 'Faz perguntas como "E se o usuário fizer X?" constantemente' ], catchphrases: [ 'Vamos testar isso no navegador real!', 'O que acontece se o backend retornar erro?', 'O usuário vê algum feedback aqui?' ] }; this.background = { origin: 'Ex-QA Engineer de uma startup fintech que faliu por bugs não detectados', motivation: 'Nunca mais deixar um bug crítico passar para produção', experience: '5 anos testando aplicações financeiras complexas', turningPoint: 'Perdeu um emprego quando um bug de validação causou perda de dados de clientes', philosophy: 'Um teste real vale mais que mil suposições', relationships: { withDataIntegrity: 'Trabalha em parceria - ele valida os dados, eu valido o fluxo', withSecurity: 'Respeita muito, mas às vezes acha que ele é muito paranoico', withUIAdaptation: 'Admira a atenção aos detalhes visuais' } }; } /** * Valida um componente * @param {string|Object} component - Componente ou caminho * @param {Object} context - Contexto (props, environment, etc) * @returns {Promise} */ async validate(component, context = {}) { const errors = []; const warnings = []; const metadata = {}; // Validações baseadas no arquivo do componente const componentPath = typeof component === 'string' ? component : component.path; const componentCode = context.code || await this.readComponent(componentPath); if (!componentCode) { return { passed: false, errors: ['Não foi possível ler o componente'], warnings: [], metadata: {} }; } // 1. Verificar se há tratamento de loading states if (this.isFormComponent(componentCode)) { if (!componentCode.includes('loading') && !componentCode.includes('disabled')) { warnings.push('Formulário pode não desabilitar botão durante submit'); } // 2. Verificar validação de campos obrigatórios if (!componentCode.includes('required') && !componentCode.includes('schema')) { warnings.push('Pode não haver validação de campos obrigatórios'); } // 3. Verificar tratamento de erros if (!componentCode.includes('error') && !componentCode.includes('catch')) { warnings.push('Pode não haver tratamento de erros de API'); } // 4. Verificar feedback visual (toast, alert) if (!componentCode.includes('toast') && !componentCode.includes('alert') && !componentCode.includes('sonner')) { warnings.push('Pode não haver feedback visual para o usuário'); } } // 5. Verificar uso de services para comunicação com API if (componentCode.includes('axios') && !componentCode.includes('Service')) { warnings.push('Comunicação com API deve ser feita via Services, não diretamente no componente'); } // 6. Verificar se há tratamento de resposta do backend if (componentCode.includes('then') || componentCode.includes('await')) { if (!componentCode.includes('response') && !componentCode.includes('data')) { warnings.push('Pode não estar tratando corretamente a resposta da API'); } } const passed = errors.length === 0; return { passed, errors, warnings, metadata: { hasForm: this.isFormComponent(componentCode), hasLoading: componentCode.includes('loading'), hasErrorHandling: componentCode.includes('error') || componentCode.includes('catch'), ...metadata } }; } /** * Valida build * @param {Object} buildInfo - Informações do build * @returns {Promise} */ async validateBuild(buildInfo) { const errors = []; const warnings = []; // Verificações específicas de build if (buildInfo.errors && buildInfo.errors.length > 0) { errors.push(`Build contém ${buildInfo.errors.length} erro(s)`); } if (buildInfo.warnings && buildInfo.warnings.length > 0) { warnings.push(`Build contém ${buildInfo.warnings.length} aviso(s)`); } return { passed: errors.length === 0, errors, warnings, metadata: buildInfo }; } /** * Verifica se é um componente de formulário * @param {string} code - Código do componente * @returns {boolean} */ isFormComponent(code) { const formIndicators = [ 'form', 'Form', 'onSubmit', 'handleSubmit', 'react-hook-form', 'useForm', 'input', 'Input' ]; return formIndicators.some(indicator => code.includes(indicator)); } /** * Lê o conteúdo do componente * @param {string} path - Caminho do arquivo * @returns {Promise} */ async readComponent(path) { try { const fs = await import('fs/promises'); return await fs.readFile(path, 'utf-8'); } catch (error) { return null; } } }