314 lines
11 KiB
HTML
314 lines
11 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="ru">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Test ChatControllerV2 - Smart Autoscroll</title>
|
|
<style>
|
|
body {
|
|
font-family: Arial, sans-serif;
|
|
padding: 20px;
|
|
max-width: 800px;
|
|
margin: 0 auto;
|
|
}
|
|
|
|
#chat-container {
|
|
border: 1px solid #ccc;
|
|
height: 400px;
|
|
overflow-y: auto;
|
|
padding: 10px;
|
|
margin-bottom: 20px;
|
|
position: relative;
|
|
background: #f9f9f9;
|
|
}
|
|
|
|
.message {
|
|
padding: 8px 12px;
|
|
margin: 5px 0;
|
|
border-radius: 8px;
|
|
background: white;
|
|
}
|
|
|
|
.message.own {
|
|
background: #007bff;
|
|
color: white;
|
|
margin-left: auto;
|
|
max-width: 70%;
|
|
}
|
|
|
|
.message.other {
|
|
background: #e9ecef;
|
|
max-width: 70%;
|
|
}
|
|
|
|
.new-messages-indicator {
|
|
position: absolute;
|
|
bottom: 20px;
|
|
left: 50%;
|
|
transform: translateX(-50%);
|
|
background: #007bff;
|
|
color: white;
|
|
border: none;
|
|
padding: 10px 20px;
|
|
border-radius: 20px;
|
|
cursor: pointer;
|
|
display: none;
|
|
align-items: center;
|
|
gap: 8px;
|
|
box-shadow: 0 2px 8px rgba(0,0,0,0.2);
|
|
z-index: 1000;
|
|
}
|
|
|
|
.new-messages-indicator.show {
|
|
display: flex;
|
|
}
|
|
|
|
.new-messages-indicator .badge {
|
|
background: rgba(255,255,255,0.3);
|
|
padding: 2px 8px;
|
|
border-radius: 10px;
|
|
font-weight: bold;
|
|
}
|
|
|
|
.controls {
|
|
display: flex;
|
|
gap: 10px;
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
button {
|
|
padding: 8px 16px;
|
|
border: none;
|
|
background: #007bff;
|
|
color: white;
|
|
border-radius: 4px;
|
|
cursor: pointer;
|
|
}
|
|
|
|
button:hover {
|
|
background: #0056b3;
|
|
}
|
|
|
|
.test-results {
|
|
margin-top: 20px;
|
|
padding: 15px;
|
|
border: 1px solid #ccc;
|
|
border-radius: 4px;
|
|
background: #f9f9f9;
|
|
}
|
|
|
|
.test-pass {
|
|
color: green;
|
|
font-weight: bold;
|
|
}
|
|
|
|
.test-fail {
|
|
color: red;
|
|
font-weight: bold;
|
|
}
|
|
|
|
.log {
|
|
margin-top: 10px;
|
|
padding: 10px;
|
|
background: #222;
|
|
color: #0f0;
|
|
font-family: 'Courier New', monospace;
|
|
font-size: 12px;
|
|
max-height: 200px;
|
|
overflow-y: auto;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<h1>ChatControllerV2 - Smart Autoscroll Test</h1>
|
|
|
|
<div class="controls">
|
|
<button onclick="testAddOwnMessage()">Добавить своё сообщение</button>
|
|
<button onclick="testAddOtherMessage()">Добавить чужое сообщение</button>
|
|
<button onclick="testScrollUp()">Прокрутить вверх</button>
|
|
<button onclick="testScrollDown()">Прокрутить вниз</button>
|
|
<button onclick="runAllTests()">Запустить все тесты</button>
|
|
</div>
|
|
|
|
<div id="chat-container"></div>
|
|
|
|
<div class="test-results">
|
|
<h3>Результаты тестов:</h3>
|
|
<div id="test-output">Нажмите "Запустить все тесты"</div>
|
|
</div>
|
|
|
|
<div class="log" id="log"></div>
|
|
|
|
<script type="module">
|
|
import { ChatControllerV2 } from './static/js/controllers/chatControllerV2.js';
|
|
import { MessageStoreV2 } from './static/js/stores/messageStoreV2.js';
|
|
|
|
// Логирование
|
|
const log = (msg) => {
|
|
const logEl = document.getElementById('log');
|
|
logEl.textContent += `[${new Date().toLocaleTimeString()}] ${msg}\n`;
|
|
logEl.scrollTop = logEl.scrollHeight;
|
|
console.log(msg);
|
|
};
|
|
|
|
// Инициализация
|
|
let controller;
|
|
let messageId = 1;
|
|
const currentUserId = 1;
|
|
const otherUserId = 2;
|
|
|
|
async function init() {
|
|
const scrollEl = document.getElementById('chat-container');
|
|
|
|
controller = new ChatControllerV2({
|
|
chatId: 1,
|
|
scrollElement: scrollEl,
|
|
containerId: 'chat-container',
|
|
currentUserId: currentUserId
|
|
});
|
|
|
|
// Добавляем несколько начальных сообщений
|
|
for (let i = 0; i < 10; i++) {
|
|
const msg = {
|
|
id: messageId++,
|
|
chat_id: 1,
|
|
author_id: i % 2 === 0 ? currentUserId : otherUserId,
|
|
content: `Тестовое сообщение ${i + 1}`,
|
|
created_at: new Date().toISOString(),
|
|
author_name: i % 2 === 0 ? 'Я' : 'Собеседник'
|
|
};
|
|
|
|
controller.store.addMessage(msg);
|
|
}
|
|
|
|
await controller.init();
|
|
log('✅ ChatControllerV2 инициализирован');
|
|
}
|
|
|
|
// Тестовые функции
|
|
window.testAddOwnMessage = async function() {
|
|
const msg = {
|
|
id: messageId++,
|
|
chat_id: 1,
|
|
author_id: currentUserId,
|
|
content: `Моё сообщение ${messageId}`,
|
|
created_at: new Date().toISOString(),
|
|
author_name: 'Я'
|
|
};
|
|
|
|
controller.store.addMessage(msg);
|
|
log(`📤 Добавлено своё сообщение #${msg.id}`);
|
|
};
|
|
|
|
window.testAddOtherMessage = async function() {
|
|
const msg = {
|
|
id: messageId++,
|
|
chat_id: 1,
|
|
author_id: otherUserId,
|
|
content: `Чужое сообщение ${messageId}`,
|
|
created_at: new Date().toISOString(),
|
|
author_name: 'Собеседник'
|
|
};
|
|
|
|
controller.store.addMessage(msg);
|
|
log(`📥 Добавлено чужое сообщение #${msg.id}`);
|
|
};
|
|
|
|
window.testScrollUp = function() {
|
|
const scrollEl = document.getElementById('chat-container');
|
|
scrollEl.scrollTop = 0;
|
|
log('⬆️ Прокручено вверх');
|
|
};
|
|
|
|
window.testScrollDown = function() {
|
|
const scrollEl = document.getElementById('chat-container');
|
|
scrollEl.scrollTop = scrollEl.scrollHeight;
|
|
log('⬇️ Прокручено вниз');
|
|
};
|
|
|
|
// Автотесты
|
|
window.runAllTests = async function() {
|
|
const output = document.getElementById('test-output');
|
|
output.innerHTML = '<p>Запуск тестов...</p>';
|
|
|
|
const results = [];
|
|
const sleep = (ms) => new Promise(r => setTimeout(r, ms));
|
|
|
|
// Тест 1: Своё сообщение - автоскролл вниз
|
|
log('🧪 Тест 1: Своё сообщение → автоскролл');
|
|
testScrollDown();
|
|
await sleep(200);
|
|
const oldScroll = controller.scrollElement.scrollTop;
|
|
testAddOwnMessage();
|
|
await sleep(500);
|
|
const newScroll = controller.scrollElement.scrollTop;
|
|
const test1 = newScroll > oldScroll;
|
|
results.push({ name: 'Своё сообщение автоскроллит', pass: test1 });
|
|
log(test1 ? '✅ PASS' : '❌ FAIL');
|
|
|
|
// Тест 2: Чужое сообщение внизу - автоскролл
|
|
log('🧪 Тест 2: Чужое сообщение внизу → автоскролл');
|
|
testScrollDown();
|
|
await sleep(200);
|
|
const oldScroll2 = controller.scrollElement.scrollTop;
|
|
testAddOtherMessage();
|
|
await sleep(500);
|
|
const newScroll2 = controller.scrollElement.scrollTop;
|
|
const test2 = newScroll2 > oldScroll2;
|
|
results.push({ name: 'Чужое сообщение внизу автоскроллит', pass: test2 });
|
|
log(test2 ? '✅ PASS' : '❌ FAIL');
|
|
|
|
// Тест 3: Чужое сообщение вверху - индикатор
|
|
log('🧪 Тест 3: Чужое сообщение вверху → индикатор');
|
|
testScrollUp();
|
|
await sleep(200);
|
|
testAddOtherMessage();
|
|
await sleep(500);
|
|
const indicator = document.getElementById('new-messages-btn');
|
|
const test3 = indicator && indicator.style.display !== 'none';
|
|
results.push({ name: 'Индикатор показывается', pass: test3 });
|
|
log(test3 ? '✅ PASS' : '❌ FAIL');
|
|
|
|
// Тест 4: Счётчик увеличивается
|
|
log('🧪 Тест 4: Счётчик увеличивается');
|
|
const countBefore = controller._newMessagesCount;
|
|
testAddOtherMessage();
|
|
await sleep(500);
|
|
const countAfter = controller._newMessagesCount;
|
|
const test4 = countAfter > countBefore;
|
|
results.push({ name: 'Счётчик увеличивается', pass: test4 });
|
|
log(test4 ? '✅ PASS' : '❌ FAIL');
|
|
|
|
// Тест 5: Клик по индикатору → скролл вниз + скрытие
|
|
log('🧪 Тест 5: Клик по индикатору → скролл + скрытие');
|
|
if (indicator) {
|
|
indicator.click();
|
|
await sleep(500);
|
|
const isHidden = indicator.style.display === 'none';
|
|
const isBottom = controller.scrollManager.isNearBottom();
|
|
const test5 = isHidden && isBottom;
|
|
results.push({ name: 'Клик работает корректно', pass: test5 });
|
|
log(test5 ? '✅ PASS' : '❌ FAIL');
|
|
}
|
|
|
|
// Вывод результатов
|
|
const passed = results.filter(r => r.pass).length;
|
|
const total = results.length;
|
|
const passRate = ((passed / total) * 100).toFixed(1);
|
|
|
|
let html = `<h4>Результаты: ${passed}/${total} (${passRate}%)</h4><ul>`;
|
|
results.forEach(r => {
|
|
html += `<li class="${r.pass ? 'test-pass' : 'test-fail'}">${r.pass ? '✅' : '❌'} ${r.name}</li>`;
|
|
});
|
|
html += '</ul>';
|
|
|
|
output.innerHTML = html;
|
|
log(`\n📊 Итого: ${passed}/${total} тестов пройдено (${passRate}%)`);
|
|
};
|
|
|
|
// Автозапуск
|
|
init();
|
|
</script>
|
|
</body>
|
|
</html>
|