import os import re import json import pathspec def scan_routes(start_path='.', doc_output='docs/manual_desenvolvimento/06_Rotas_E_Telas.md', json_output='qa_routes.json', gitignore_file='.gitignore'): """ Escaneia o projeto em busca de rotas e gera documentação + config de QA. """ # 1. Configuração de Ignorados ignore_patterns = ['.git', '.agent', 'node_modules', 'venv', 'dist', 'build', 'test-results'] if os.path.exists(gitignore_file): with open(gitignore_file, 'r', encoding='utf-8') as f: ignore_patterns.extend(f.read().splitlines()) spec = pathspec.PathSpec.from_lines('gitwildmatch', ignore_patterns) # 2. Padrões de Detecção (Regex) - ADAPTAR CONFORME SEU FRAMEWORK # Captura: path: "/login", path: '/login', route("/login"), href="/login" route_regexes = [ r"path:\s*['\"](\/[\w\-\/]*)['\"]", # Ex: path: "/clientes" r"route\(\s*['\"](\/[\w\-\/]*)['\"]", # Ex: route('/dashboard') r"\.get\(\s*['\"](\/[\w\-\/]*)['\"]", # Ex: app.get('/api/...') r"href=['\"](\/[\w\-\/]*)['\"]" # Ex: (Simples) ] routes_found = set() files_with_routes = {} print("🛰️ Iniciando varredura de rotas...") for root, dirs, files in os.walk(start_path): dirs[:] = [d for d in dirs if not spec.match_file(os.path.join(root, d))] for file in files: file_path = os.path.join(root, file) if spec.match_file(file_path): continue # Estratégia A: Arquivos HTML são rotas por si só (se for estático) if file.endswith('.html'): relative_path = os.path.relpath(file_path, start_path).replace('\\', '/') # Se estiver na raiz, a rota é /nome.html ou /nome route_name = f"/{relative_path}" routes_found.add(route_name) files_with_routes[route_name] = file_path continue # Estratégia B: Varrer JS/TS buscando definições if file.endswith(('.js', '.ts', '.jsx', '.vue', '.php')): try: with open(file_path, 'r', encoding='utf-8', errors='ignore') as f: content = f.read() for pattern in route_regexes: matches = re.finditer(pattern, content) for match in matches: route = match.group(1) # Ignora rotas muito curtas ou genéricas demais se necessário if len(route) > 1: routes_found.add(route) files_with_routes[route] = file_path except Exception: pass # 3. Ordenação e Limpeza sorted_routes = sorted(list(routes_found)) # 4. Gerar JSON para QA (qa_snapshot_spree.py) qa_config = [] for route in sorted_routes: qa_config.append({ "name": route.strip('/').capitalize() or "Home", "path": route, # Adiciona espera inteligente se for dashboard "wait_for": "body" }) with open(json_output, 'w', encoding='utf-8') as f: json.dump(qa_config, f, indent=2) # 5. Gerar Markdown (Documentação) os.makedirs(os.path.dirname(doc_output), exist_ok=True) md_content = [ "# 🗺️ Mapa de Rotas e Telas", f"> Gerado automaticamente via `route_scanner.py`. Total: **{len(sorted_routes)}**", "", "| Rota (URL) | Arquivo Fonte Detectado | Nome Sugerido |", "| :--- | :--- | :--- |" ] for route in sorted_routes: source = files_with_routes.get(route, "Auto-detected") name = route.strip('/').capitalize() or "Home" md_content.append(f"| `{route}` | `{source}` | {name} |") md_content.append("") md_content.append("## 🤖 Integração QA") md_content.append(f"Este mapeamento atualizou automaticamente o arquivo `{json_output}` usado pelos testes automatizados.") with open(doc_output, 'w', encoding='utf-8') as f: f.write('\n'.join(md_content)) return f"✅ Rotas mapeadas!\n 📄 Docs: {doc_output}\n ⚙️ Config QA: {json_output}" if __name__ == "__main__": print(scan_routes())