logboard/test_browser.html
Сергей Антропов 85757ca717 fix: добавлен CORS middleware и тестовые файлы для диагностики
- Добавлен CORSMiddleware в app.py для решения проблем с CORS
- Создан test_api.py для тестирования API endpoints
- Создан test_websocket.py для тестирования WebSocket соединений
- Создан test_browser.html для тестирования в браузере
- Все тесты показывают, что API и WebSocket работают корректно

Диагностика показала:
 API endpoints работают (health, auth, containers, logs)
 WebSocket соединения работают и передают логи
 Проблема может быть в браузере или localStorage

Для тестирования в браузере:
1. Откройте http://localhost:9001/test_browser.html
2. Выполните тесты по порядку
3. Проверьте консоль браузера на ошибки

Автор: Сергей Антропов
Сайт: https://devops.org.ru
2025-08-20 20:50:28 +03:00

200 lines
8.4 KiB
HTML

<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Тест LogBoard+ API</title>
<style>
body { font-family: Arial, sans-serif; margin: 20px; }
.test-section { margin: 20px 0; padding: 15px; border: 1px solid #ccc; border-radius: 5px; }
.success { color: green; }
.error { color: red; }
.info { color: blue; }
button { padding: 10px 20px; margin: 5px; }
pre { background: #f5f5f5; padding: 10px; border-radius: 3px; overflow-x: auto; }
</style>
</head>
<body>
<h1>Тест LogBoard+ API</h1>
<div class="test-section">
<h3>1. Проверка токена в localStorage</h3>
<button onclick="checkToken()">Проверить токен</button>
<div id="tokenResult"></div>
</div>
<div class="test-section">
<h3>2. Тест входа в систему</h3>
<button onclick="testLogin()">Войти (admin/admin)</button>
<div id="loginResult"></div>
</div>
<div class="test-section">
<h3>3. Тест получения контейнеров</h3>
<button onclick="testContainers()">Получить контейнеры</button>
<div id="containersResult"></div>
</div>
<div class="test-section">
<h3>4. Тест WebSocket</h3>
<button onclick="testWebSocket()">Тест WebSocket</button>
<div id="websocketResult"></div>
</div>
<div class="test-section">
<h3>5. Очистка</h3>
<button onclick="clearToken()">Очистить токен</button>
<div id="clearResult"></div>
</div>
<script>
const baseUrl = 'http://localhost:9001';
function log(elementId, message, type = 'info') {
const element = document.getElementById(elementId);
const className = type === 'success' ? 'success' : type === 'error' ? 'error' : 'info';
element.innerHTML = `<div class="${className}">${message}</div>`;
}
function checkToken() {
const token = localStorage.getItem('access_token');
if (token) {
log('tokenResult', `✅ Токен найден: ${token.substring(0, 50)}...`, 'success');
} else {
log('tokenResult', '❌ Токен не найден', 'error');
}
}
async function testLogin() {
try {
log('loginResult', '🔄 Выполняется вход...', 'info');
const response = await fetch(`${baseUrl}/api/auth/login`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
username: 'admin',
password: 'admin'
})
});
if (response.ok) {
const data = await response.json();
localStorage.setItem('access_token', data.access_token);
log('loginResult', `✅ Вход выполнен успешно! Токен сохранен.`, 'success');
} else {
const errorData = await response.json();
log('loginResult', `❌ Ошибка входа: ${errorData.detail || response.status}`, 'error');
}
} catch (error) {
log('loginResult', `❌ Ошибка: ${error.message}`, 'error');
}
}
async function testContainers() {
try {
const token = localStorage.getItem('access_token');
if (!token) {
log('containersResult', '❌ Токен не найден. Сначала выполните вход.', 'error');
return;
}
log('containersResult', '🔄 Получение контейнеров...', 'info');
const response = await fetch(`${baseUrl}/api/containers/services`, {
headers: {
'Authorization': `Bearer ${token}`
}
});
if (response.ok) {
const containers = await response.json();
log('containersResult', `✅ Получено контейнеров: ${containers.length}`, 'success');
const containerList = containers.slice(0, 3).map(c =>
`${c.name} (${c.status})`
).join('<br>');
document.getElementById('containersResult').innerHTML +=
`<div class="success">Первые 3 контейнера:<br>${containerList}</div>`;
} else {
const errorText = await response.text();
log('containersResult', `❌ Ошибка: ${response.status} - ${errorText}`, 'error');
}
} catch (error) {
log('containersResult', `❌ Ошибка: ${error.message}`, 'error');
}
}
function testWebSocket() {
const token = localStorage.getItem('access_token');
if (!token) {
log('websocketResult', '❌ Токен не найден. Сначала выполните вход.', 'error');
return;
}
log('websocketResult', '🔄 Подключение к WebSocket...', 'info');
// Получаем первый контейнер для теста
fetch(`${baseUrl}/api/containers/services`, {
headers: {
'Authorization': `Bearer ${token}`
}
})
.then(response => response.json())
.then(containers => {
if (containers.length === 0) {
log('websocketResult', '❌ Нет контейнеров для тестирования', 'error');
return;
}
const container = containers[0];
const wsUrl = `ws://localhost:9001/api/websocket/logs/${container.id}?tail=5&token=${token}&service=${container.name}`;
log('websocketResult', `🔗 Подключение к: ${wsUrl.substring(0, 80)}...`, 'info');
const ws = new WebSocket(wsUrl);
ws.onopen = function() {
log('websocketResult', '✅ WebSocket соединение установлено!', 'success');
};
ws.onmessage = function(event) {
const message = event.data;
log('websocketResult', `📨 Получено сообщение: ${message.substring(0, 100)}...`, 'success');
// Закрываем соединение после получения первого сообщения
setTimeout(() => {
ws.close();
log('websocketResult', '🔌 WebSocket соединение закрыто', 'info');
}, 1000);
};
ws.onerror = function(error) {
log('websocketResult', `❌ WebSocket ошибка: ${error}`, 'error');
};
ws.onclose = function() {
log('websocketResult', '🔌 WebSocket соединение закрыто', 'info');
};
})
.catch(error => {
log('websocketResult', `❌ Ошибка получения контейнеров: ${error.message}`, 'error');
});
}
function clearToken() {
localStorage.removeItem('access_token');
log('clearResult', '✅ Токен очищен', 'success');
}
// Автоматическая проверка токена при загрузке
window.onload = function() {
checkToken();
};
</script>
</body>
</html>