Files
agents/TesterAgent.py
T
2026-09-19 13:18:49 +00:00

101 lines
5.1 KiB
Python

from start import Project
class TesterAgent:
"""Агент-тестировщик: открывает браузер, проверяет консоль на ошибки."""
@staticmethod
def test(project: Project) -> List[Dict[str, Any]]:
print(f"🌐 Тестировщик проверяет {project.url} ...")
errors = []
try:
with sync_playwright() as p:
browser = p.chromium.launch(headless=True)
context = browser.new_context()
page = context.new_page()
console_errors = []
# Перехват ошибок страницы (даёт объект Error)
def handle_pageerror(error):
error_info = {
"message": str(error),
"type": "pageerror",
"location": None,
"stack": error.stack if hasattr(error, 'stack') else None
}
# Извлекаем location из стека, если есть
if error_info["stack"]:
import re
# Ищем строки вида at ... (file:line:col)
match = re.search(r'at .*?\((.*?):(\d+):(\d+)\)', error_info["stack"])
if match:
file_path = match.group(1)
line = int(match.group(2))
col = int(match.group(3))
error_info["location"] = {"url": file_path, "line": line, "column": col}
console_errors.append(error_info)
page.on("pageerror", handle_pageerror)
# Обработка console сообщений
def handle_console(msg):
if msg.type in ("error", "warning"):
error_info = {
"message": msg.text,
"type": msg.type,
"location": None,
"stack": None
}
# Местоположение (уже есть)
if hasattr(msg, 'location') and msg.location:
error_info["location"] = {
"url": msg.location.get("url", ""),
"line": msg.location.get("lineNumber", 0),
"column": msg.location.get("columnNumber", 0)
}
# Попытка извлечь стек из сообщения (часто в конце сообщения есть строки at)
if error_info["message"]:
import re
# Ищем строки, начинающиеся с 'at ' (стек)
stack_lines = re.findall(r'at .*', error_info["message"])
if stack_lines:
error_info["stack"] = "\n".join(stack_lines)
else:
# В некоторых браузерах стек может быть в конце сообщения после \n
parts = error_info["message"].split('\n')
if len(parts) > 1:
# Проверяем, есть ли строки, начинающиеся с 'at'
stack_candidate = "\n".join(
[line for line in parts if line.strip().startswith('at')])
if stack_candidate:
error_info["stack"] = stack_candidate
console_errors.append(error_info)
page.on("console", handle_console)
# Внедряем скрипт для перехвата необработанных ошибок и rejection (чтобы они попали в console)
page.add_init_script("""
window.addEventListener('error', function(e) {
console.error(e.message + '\\n' + e.stack);
});
window.addEventListener('unhandledrejection', function(e) {
console.error(e.reason.message || e.reason);
});
""")
page.goto(project.url, timeout=30000, wait_until='load')
time.sleep(2)
browser.close()
if console_errors:
errors = console_errors
else:
print(" ✅ Ошибок в консоли не обнаружено.")
except Exception as e:
errors.append({
"message": f"Ошибка запуска браузера: {e}",
"type": "error",
"location": None,
"stack": None
})
return errors