107 lines
4.3 KiB
Python
107 lines
4.3 KiB
Python
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: <a href="/perfil"> (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()) |