File size: 7,364 Bytes
e62aafd | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 | #!/usr/bin/env python3
"""
Teste WebRTC automatizado com Playwright headless
"""
import asyncio
from playwright.async_api import async_playwright
import sys
SERVER_URL = "http://62.107.25.198:47898"
async def test_webrtc():
print("="*60)
print("Teste WebRTC com Playwright (Headless)")
print("="*60)
async with async_playwright() as p:
# Iniciar browser headless
print("\n[1/6] Iniciando browser headless...")
browser = await p.chromium.launch(
headless=True,
args=[
'--use-fake-ui-for-media-stream',
'--use-fake-device-for-media-stream',
'--no-sandbox'
]
)
context = await browser.new_context(
permissions=['camera', 'microphone']
)
page = await context.new_page()
# Coletar logs do console e erros
console_logs = []
page_errors = []
page.on("console", lambda msg: console_logs.append(f"[{msg.type}] {msg.text}"))
page.on("pageerror", lambda exc: page_errors.append(f"ERROR: {exc}"))
# Capturar requests/responses
network_logs = []
def handle_response(response):
if '/offer' in response.url:
network_logs.append(f"POST /offer → Status: {response.status}")
if response.status != 200:
network_logs.append(f" Error: {response.status_text}")
page.on("response", handle_response)
# Navegar para a página
print(f"[2/6] Navegando para {SERVER_URL}...")
try:
await page.goto(SERVER_URL, timeout=10000)
print("✓ Página carregada")
except Exception as e:
print(f"✗ Erro ao carregar página: {e}")
await browser.close()
return False
# Verificar se a página carregou
print("[3/6] Verificando elementos...")
try:
await page.wait_for_selector('#btnConnect', timeout=5000)
print("✓ Botão 'Conectar' encontrado")
except Exception as e:
print(f"✗ Erro: {e}")
await browser.close()
return False
# Injetar código para capturar eventos ICE
print("[4/6] Configurando captura de eventos ICE...")
await page.evaluate("""
window.iceInfo = {
candidates: [],
states: [],
connectionStates: []
};
// Interceptar console.log de ICE candidates
const originalLog = console.log;
console.log = function(...args) {
if (args[0] === 'ICE Candidate:') {
window.iceInfo.candidates.push(args[1]);
} else if (args[0] === 'ICE State:') {
window.iceInfo.states.push(args[1]);
} else if (args[0] === 'Estado WebRTC:') {
window.iceInfo.connectionStates.push(args[1]);
}
originalLog.apply(console, args);
};
""")
# Clicar em conectar
print("[5/6] Clicando em 'Conectar'...")
await page.click('#btnConnect')
# Aguardar tentativa de conexão
print("[6/6] Aguardando conexão (15s)...")
await asyncio.sleep(15)
# Capturar informações ICE
ice_info = await page.evaluate("window.iceInfo")
# Capturar estado da conexão
webrtc_state = await page.evaluate("""
(() => {
const pc = window.pc;
if (!pc) return null;
return {
connectionState: pc.connectionState,
iceConnectionState: pc.iceConnectionState,
iceGatheringState: pc.iceGatheringState,
signalingState: pc.signalingState
};
})()
""")
# Resultados
print("\n" + "="*60)
print("RESULTADOS")
print("="*60)
if webrtc_state:
print(f"\nEstados WebRTC:")
print(f" Connection: {webrtc_state['connectionState']}")
print(f" ICE Connection: {webrtc_state['iceConnectionState']}")
print(f" ICE Gathering: {webrtc_state['iceGatheringState']}")
print(f" Signaling: {webrtc_state['signalingState']}")
else:
print("\n✗ Peer connection não foi criada!")
# Análise de candidatos ICE
candidates = ice_info.get('candidates', [])
print(f"\nCandidatos ICE: {len(candidates)}")
candidate_types = {}
for c in candidates:
ctype = c.get('type', 'unknown')
candidate_types[ctype] = candidate_types.get(ctype, 0) + 1
for ctype, count in candidate_types.items():
icon = "✓" if ctype == "relay" else "•"
print(f" {icon} {ctype}: {count}")
# Diagnóstico
print("\n" + "="*60)
print("DIAGNÓSTICO")
print("="*60)
success = False
if not webrtc_state:
print("\n✗ FALHA: Peer connection não foi criada")
print(" → Verificar JavaScript do frontend")
elif webrtc_state['connectionState'] == 'connected':
print("\n✓ SUCESSO: WebRTC conectado!")
success = True
elif webrtc_state['iceConnectionState'] == 'failed':
print("\n✗ FALHA: ICE connection failed")
if len(candidates) == 0:
print(" → Problema: Nenhum candidato ICE gerado")
print(" → Solução: Verificar configuração STUN/TURN")
elif 'relay' not in candidate_types:
print(" → Problema: Nenhum candidato TURN (relay)")
print(" → Solução: Servidores TURN não estão funcionando")
print(" → Tentar outros servidores TURN")
else:
print(" → Problema: Candidatos gerados mas não conectam")
print(" → Solução: Problema de firewall/NAT no servidor")
print(" → Verificar port mapping UDP no vast.ai")
elif webrtc_state['connectionState'] == 'connecting':
print("\n⚠ TIMEOUT: Conexão travada em 'connecting'")
print(" → Problema: ICE negotiation timeout")
print(" → Causa provável: Port mapping UDP não configurado")
print(" → Solução: Expor portas UDP no vast.ai ou usar ngrok")
# Erros de página
if page_errors:
print("\n" + "="*60)
print("ERROS JAVASCRIPT")
print("="*60)
for err in page_errors:
print(err)
# Logs de rede
if network_logs:
print("\n" + "="*60)
print("LOGS DE REDE")
print("="*60)
for log in network_logs:
print(log)
# Logs do console
if console_logs:
print("\n" + "="*60)
print("LOGS DO CONSOLE (últimos 20)")
print("="*60)
for log in console_logs[-20:]:
print(log)
await browser.close()
return success
async def main():
success = await test_webrtc()
sys.exit(0 if success else 1)
if __name__ == "__main__":
asyncio.run(main())
|