Files
crm.clientright.ru/test_mobile_keyboard_fix.html

890 lines
47 KiB
HTML
Raw Normal View History

<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<title>Тест мобильной адаптации AI Drawer</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 20px;
background: #f5f5f5;
}
.test-container {
max-width: 800px;
margin: 0 auto;
background: white;
padding: 20px;
border-radius: 10px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
.test-section {
margin-bottom: 30px;
padding: 20px;
border: 1px solid #ddd;
border-radius: 8px;
}
.test-title {
color: #007bff;
font-size: 18px;
font-weight: bold;
margin-bottom: 15px;
}
.test-description {
color: #666;
margin-bottom: 15px;
line-height: 1.5;
}
.test-button {
background: #007bff;
color: white;
border: none;
padding: 12px 24px;
border-radius: 6px;
cursor: pointer;
font-size: 16px;
margin: 5px;
}
.test-button:hover {
background: #0056b3;
}
.test-button.secondary {
background: #6c757d;
}
.test-button.secondary:hover {
background: #545b62;
}
.status {
padding: 10px;
border-radius: 5px;
margin: 10px 0;
font-weight: bold;
}
.status.success {
background: #d4edda;
color: #155724;
border: 1px solid #c3e6cb;
}
.status.info {
background: #d1ecf1;
color: #0c5460;
border: 1px solid #bee5eb;
}
.status.warning {
background: #fff3cd;
color: #856404;
border: 1px solid #ffeaa7;
}
.device-info {
background: #f8f9fa;
padding: 15px;
border-radius: 5px;
margin: 15px 0;
font-family: monospace;
font-size: 14px;
}
.instructions {
background: #e7f3ff;
padding: 15px;
border-radius: 5px;
border-left: 4px solid #007bff;
margin: 15px 0;
}
.instructions h4 {
margin-top: 0;
color: #007bff;
}
.instructions ol {
margin: 10px 0;
padding-left: 20px;
}
.instructions li {
margin: 5px 0;
}
.log-container {
background: #f8f9fa;
border: 1px solid #dee2e6;
border-radius: 5px;
padding: 15px;
margin: 15px 0;
font-family: 'Courier New', monospace;
font-size: 12px;
max-height: 300px;
overflow-y: auto;
white-space: pre-wrap;
}
.log-entry {
margin: 2px 0;
padding: 2px 5px;
border-radius: 3px;
}
.log-info {
background: #d1ecf1;
color: #0c5460;
}
.log-success {
background: #d4edda;
color: #155724;
}
.log-warning {
background: #fff3cd;
color: #856404;
}
.log-error {
background: #f8d7da;
color: #721c24;
}
.log-debug {
background: #e2e3e5;
color: #383d41;
}
</style>
</head>
<body>
<div class="test-container">
<h1>🧪 Тест мобильной адаптации AI Drawer</h1>
<div class="device-info">
<strong>Информация об устройстве:</strong><br>
Ширина экрана: <span id="screen-width">-</span>px<br>
Высота экрана: <span id="screen-height">-</span>px<br>
User Agent: <span id="user-agent">-</span><br>
Мобильное устройство: <span id="is-mobile">-</span>
</div>
<div class="test-section">
<div class="test-title">📱 Тест 1: Открытие AI Drawer на мобильном</div>
<div class="test-description">
Проверяем, что AI Drawer корректно открывается на мобильных устройствах и занимает всю ширину экрана.
</div>
<button class="test-button" onclick="testOpenDrawer()">Открыть AI Drawer</button>
<button class="test-button secondary" onclick="testCloseDrawer()">Закрыть AI Drawer</button>
<div id="test1-status"></div>
</div>
<div class="test-section">
<div class="test-title">⌨️ Тест 2: Адаптация к виртуальной клавиатуре</div>
<div class="test-description">
Проверяем, что поле ввода остается доступным при появлении виртуальной клавиатуры, правильно ужимается под размер экрана и поднимается выше от нижнего края.
</div>
<div class="instructions">
<h4>Инструкции для тестирования:</h4>
<ol>
<li>Откройте AI Drawer</li>
<li>Нажмите на поле ввода сообщения</li>
<li>Проверьте, что поле ввода и кнопка "Отправить" остаются видимыми</li>
<li>Проверьте, что поле ввода ужимается под размер экрана</li>
<li>Проверьте, что поле ввода поднимается выше от нижнего края (20-40px)</li>
<li>Проверьте, что кнопка "Отправить" не перекрывается</li>
<li>Проверьте, что чат автоматически прокручивается к последнему сообщению</li>
</ol>
</div>
<button class="test-button" onclick="testKeyboardAdaptation()">Начать тест клавиатуры</button>
<div id="test2-status"></div>
</div>
<div class="test-section">
<div class="test-title">📏 Тест 3: Размеры элементов на мобильном</div>
<div class="test-description">
Проверяем, что все элементы имеют подходящие размеры для мобильных устройств.
</div>
<button class="test-button" onclick="testElementSizes()">Проверить размеры</button>
<div id="test3-status"></div>
</div>
<div class="test-section">
<div class="test-title">🔄 Тест 4: Прокрутка и навигация</div>
<div class="test-description">
Проверяем плавность прокрутки и навигации в чате.
</div>
<button class="test-button" onclick="testScrolling()">Тест прокрутки</button>
<div id="test4-status"></div>
</div>
<div class="test-section">
<div class="test-title">🎨 Тест 5: Адаптивность интерфейса</div>
<div class="test-description">
Проверяем, что интерфейс корректно адаптируется к разным размерам экрана.
</div>
<button class="test-button" onclick="testResponsiveness()">Тест адаптивности</button>
<div id="test5-status"></div>
</div>
<div class="instructions">
<h4>🔧 Дополнительные тесты:</h4>
<ol>
<li><strong>Поворот экрана:</strong> Поверните устройство и проверьте адаптацию</li>
<li><strong>Разные браузеры:</strong> Протестируйте в Chrome, Safari, Firefox</li>
<li><strong>Разные размеры экрана:</strong> Протестируйте на разных устройствах</li>
<li><strong>Производительность:</strong> Проверьте плавность анимаций</li>
</ol>
</div>
<div class="test-section">
<div class="test-title">📋 Лог тестирования</div>
<div class="test-description">
Здесь отображаются подробные логи всех тестов и проверок.
</div>
<button class="test-button secondary" onclick="clearLog()">Очистить лог</button>
<button class="test-button secondary" onclick="exportLog()">Экспорт лога</button>
<button class="test-button secondary" onclick="loadServerLogs()">Загрузить с сервера</button>
<button class="test-button secondary" onclick="clearServerLogs()">Очистить сервер</button>
<button class="test-button secondary" onclick="checkServerStatus()">Статус сервера</button>
<div id="test-log" class="log-container"></div>
</div>
</div>
<!-- Подключаем AI Drawer -->
<link rel="stylesheet" href="layouts/v7/resources/css/ai-drawer.css">
<script src="layouts/v7/resources/js/ai-drawer.js"></script>
<script>
// Система логирования
let testLog = [];
function addLog(message, type = 'info', details = null) {
const timestamp = new Date().toLocaleTimeString();
const logEntry = {
timestamp: timestamp,
message: message,
type: type,
details: details,
userAgent: navigator.userAgent,
screenSize: `${window.innerWidth}x${window.innerHeight}`,
url: window.location.href
};
testLog.push(logEntry);
const logContainer = document.getElementById('test-log');
if (logContainer) {
const logElement = document.createElement('div');
logElement.className = `log-entry log-${type}`;
let logText = `[${timestamp}] ${message}`;
if (details) {
logText += `\nДетали: ${JSON.stringify(details, null, 2)}`;
}
logElement.textContent = logText;
logContainer.appendChild(logElement);
logContainer.scrollTop = logContainer.scrollHeight;
}
// Также выводим в консоль браузера
console.log(`[TEST LOG ${type.toUpperCase()}] ${message}`, details || '');
// Отправляем на сервер
sendLogToServer(logEntry);
}
function sendLogToServer(logEntry) {
fetch('/test_log_server.php?action=write', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(logEntry)
}).catch(error => {
console.warn('Не удалось отправить лог на сервер:', error);
});
}
function clearLog() {
testLog = [];
const logContainer = document.getElementById('test-log');
if (logContainer) {
logContainer.innerHTML = '';
}
addLog('Лог очищен', 'info');
}
function exportLog() {
const logText = testLog.map(entry =>
`[${entry.timestamp}] ${entry.type.toUpperCase()}: ${entry.message}` +
(entry.details ? `\nДетали: ${JSON.stringify(entry.details, null, 2)}` : '')
).join('\n\n');
const blob = new Blob([logText], { type: 'text/plain' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `ai-drawer-test-log-${new Date().toISOString().slice(0, 19)}.txt`;
a.click();
URL.revokeObjectURL(url);
addLog('Лог экспортирован', 'success');
}
function loadServerLogs() {
fetch('/test_log_server.php?action=read&limit=50')
.then(response => response.json())
.then(data => {
if (data.success) {
addLog(`Загружено ${data.logs.length} записей с сервера`, 'info');
// Добавляем серверные логи в контейнер
const logContainer = document.getElementById('test-log');
if (logContainer) {
data.logs.forEach(logEntry => {
const logElement = document.createElement('div');
logElement.className = `log-entry log-${logEntry.data.type || 'info'}`;
logElement.style.opacity = '0.7'; // Помечаем как серверные
let logText = `[СЕРВЕР ${logEntry.timestamp}] ${logEntry.data.message}`;
if (logEntry.data.details) {
logText += `\nДетали: ${JSON.stringify(logEntry.data.details, null, 2)}`;
}
logElement.textContent = logText;
logContainer.insertBefore(logElement, logContainer.firstChild);
});
}
} else {
addLog('Ошибка загрузки серверных логов', 'error', data.message);
}
})
.catch(error => {
addLog('Ошибка подключения к серверу логов', 'error', error.message);
});
}
function clearServerLogs() {
fetch('/test_log_server.php?action=clear')
.then(response => response.json())
.then(data => {
if (data.success) {
addLog('Серверные логи очищены', 'success');
} else {
addLog('Ошибка очистки серверных логов', 'error', data.message);
}
})
.catch(error => {
addLog('Ошибка подключения к серверу логов', 'error', error.message);
});
}
function checkServerStatus() {
fetch('/test_log_server.php?action=status')
.then(response => response.json())
.then(data => {
if (data.success) {
addLog('Статус сервера логов', 'info', data.status);
} else {
addLog('Ошибка получения статуса сервера', 'error', data.message);
}
})
.catch(error => {
addLog('Сервер логов недоступен', 'warning', error.message);
});
}
// Обновляем информацию об устройстве
function updateDeviceInfo() {
document.getElementById('screen-width').textContent = window.innerWidth;
document.getElementById('screen-height').textContent = window.innerHeight;
document.getElementById('user-agent').textContent = navigator.userAgent.substring(0, 50) + '...';
document.getElementById('is-mobile').textContent = window.innerWidth <= 768 ? 'Да' : 'Нет';
addLog('Информация об устройстве обновлена', 'info', {
width: window.innerWidth,
height: window.innerHeight,
isMobile: window.innerWidth <= 768,
userAgent: navigator.userAgent
});
}
// Обновляем информацию при изменении размера окна
window.addEventListener('resize', updateDeviceInfo);
updateDeviceInfo();
// Инициализируем AI Drawer
let aiDrawerInstance;
document.addEventListener('DOMContentLoaded', function() {
addLog('Начало инициализации AI Drawer', 'info');
try {
aiDrawerInstance = new AIDrawer();
addLog('AI Drawer успешно инициализирован', 'success', {
drawer: !!aiDrawerInstance.drawer,
toggleBtn: !!aiDrawerInstance.toggleBtn,
closeBtn: !!aiDrawerInstance.closeBtn,
chatInput: !!aiDrawerInstance.chatInput,
sendButton: !!aiDrawerInstance.sendButton
});
} catch (error) {
addLog('Ошибка инициализации AI Drawer', 'error', {
error: error.message,
stack: error.stack
});
}
});
// Тест 1: Открытие/закрытие drawer
function testOpenDrawer() {
const status = document.getElementById('test1-status');
addLog('Начало теста: Открытие AI Drawer', 'info');
try {
if (aiDrawerInstance) {
aiDrawerInstance.open();
addLog('AI Drawer открыт', 'success');
status.innerHTML = '<div class="status success">✅ AI Drawer успешно открыт</div>';
// Проверяем размеры
setTimeout(() => {
const drawer = document.querySelector('.ai-drawer');
if (drawer) {
const rect = drawer.getBoundingClientRect();
const isFullWidth = window.innerWidth <= 768 ? rect.width >= window.innerWidth * 0.95 : rect.width >= 350;
addLog('Проверка размеров drawer', 'debug', {
drawerWidth: rect.width,
screenWidth: window.innerWidth,
isMobile: window.innerWidth <= 768,
isFullWidth: isFullWidth,
expectedMinWidth: window.innerWidth <= 768 ? window.innerWidth * 0.95 : 350
});
if (isFullWidth) {
status.innerHTML += '<div class="status success">✅ Размеры drawer корректны</div>';
addLog('Размеры drawer корректны', 'success');
} else {
status.innerHTML += '<div class="status warning">⚠️ Размеры drawer могут быть некорректными</div>';
addLog('Размеры drawer некорректны', 'warning', {
actualWidth: rect.width,
expectedMinWidth: window.innerWidth <= 768 ? window.innerWidth * 0.95 : 350
});
}
} else {
addLog('Drawer элемент не найден', 'error');
}
}, 500);
} else {
status.innerHTML = '<div class="status warning">⚠️ AI Drawer не инициализирован</div>';
addLog('AI Drawer не инициализирован', 'error');
}
} catch (error) {
status.innerHTML = '<div class="status warning">⚠️ Ошибка: ' + error.message + '</div>';
addLog('Ошибка при открытии drawer', 'error', {
error: error.message,
stack: error.stack
});
}
}
function testCloseDrawer() {
const status = document.getElementById('test1-status');
try {
if (aiDrawerInstance) {
aiDrawerInstance.close();
status.innerHTML = '<div class="status success">✅ AI Drawer успешно закрыт</div>';
} else {
status.innerHTML = '<div class="status warning">⚠️ AI Drawer не инициализирован</div>';
}
} catch (error) {
status.innerHTML = '<div class="status warning">⚠️ Ошибка: ' + error.message + '</div>';
}
}
// Тест 2: Адаптация к клавиатуре
function testKeyboardAdaptation() {
const status = document.getElementById('test2-status');
addLog('Начало теста: Адаптация к виртуальной клавиатуре', 'info');
try {
if (aiDrawerInstance) {
aiDrawerInstance.open();
addLog('AI Drawer открыт для теста клавиатуры', 'info');
// Добавляем тестовые сообщения
aiDrawerInstance.addMessage('Тестовое сообщение 1', false);
aiDrawerInstance.addMessage('Тестовое сообщение 2', true);
aiDrawerInstance.addMessage('Тестовое сообщение 3', false);
addLog('Добавлены тестовые сообщения', 'info');
status.innerHTML = '<div class="status info"> Добавлены тестовые сообщения. Теперь нажмите на поле ввода для проверки адаптации к клавиатуре.</div>';
// Проверяем поле ввода
const input = document.querySelector('#ai-chat-input');
if (input) {
addLog('Поле ввода найдено, добавляем обработчик фокуса', 'info');
input.addEventListener('focus', function() {
addLog('Поле ввода получило фокус', 'info');
setTimeout(() => {
const inputContainer = document.querySelector('.ai-chat-input-container');
const inputField = document.querySelector('#ai-chat-input');
const sendButton = document.querySelector('#ai-send-button');
addLog('Начало проверки элементов после фокуса', 'debug', {
inputContainer: !!inputContainer,
inputField: !!inputField,
sendButton: !!sendButton
});
// Проверяем видимость контейнера
const containerRect = inputContainer.getBoundingClientRect();
const isContainerVisible = containerRect.top >= 0 && containerRect.bottom <= window.innerHeight;
// Проверяем размеры поля ввода
const inputRect = inputField.getBoundingClientRect();
const inputWidth = inputRect.width;
const screenWidth = window.innerWidth;
const inputWidthPercent = (inputWidth / screenWidth) * 100;
// Проверяем видимость кнопки отправки
const buttonRect = sendButton.getBoundingClientRect();
const isButtonVisible = buttonRect.top >= 0 && buttonRect.bottom <= window.innerHeight;
// Проверяем высоту поля ввода от нижнего края
const inputBottom = inputRect.bottom;
const screenHeight = window.innerHeight;
const distanceFromBottom = screenHeight - inputBottom;
addLog('Измерения элементов', 'debug', {
containerRect: {
top: containerRect.top,
bottom: containerRect.bottom,
left: containerRect.left,
right: containerRect.right,
width: containerRect.width,
height: containerRect.height
},
inputRect: {
top: inputRect.top,
bottom: inputRect.bottom,
left: inputRect.left,
right: inputRect.right,
width: inputRect.width,
height: inputRect.height
},
buttonRect: {
top: buttonRect.top,
bottom: buttonRect.bottom,
left: buttonRect.left,
right: buttonRect.right,
width: buttonRect.width,
height: buttonRect.height
},
screenDimensions: {
width: screenWidth,
height: screenHeight
},
calculations: {
inputWidthPercent: inputWidthPercent,
distanceFromBottom: distanceFromBottom,
isContainerVisible: isContainerVisible,
isButtonVisible: isButtonVisible
}
});
if (isContainerVisible) {
status.innerHTML += '<div class="status success">✅ Поле ввода остается видимым при появлении клавиатуры</div>';
addLog('Поле ввода остается видимым', 'success');
} else {
status.innerHTML += '<div class="status warning">⚠️ Поле ввода может быть скрыто клавиатурой</div>';
addLog('Поле ввода может быть скрыто клавиатурой', 'warning');
}
if (inputWidthPercent >= 60 && inputWidthPercent <= 80) {
status.innerHTML += '<div class="status success">✅ Поле ввода правильно ужимается под размер экрана (' + Math.round(inputWidthPercent) + '%)</div>';
addLog('Поле ввода правильно ужимается', 'success', { widthPercent: inputWidthPercent });
} else {
status.innerHTML += '<div class="status warning">⚠️ Поле ввода может быть слишком широким или узким (' + Math.round(inputWidthPercent) + '%)</div>';
addLog('Поле ввода неправильно ужимается', 'warning', { widthPercent: inputWidthPercent });
}
if (isButtonVisible) {
status.innerHTML += '<div class="status success">✅ Кнопка "Отправить" остается видимой</div>';
addLog('Кнопка "Отправить" остается видимой', 'success');
} else {
status.innerHTML += '<div class="status warning">⚠️ Кнопка "Отправить" может быть перекрыта</div>';
addLog('Кнопка "Отправить" может быть перекрыта', 'warning');
}
if (distanceFromBottom >= 200 && distanceFromBottom <= 400) {
status.innerHTML += '<div class="status success">✅ Поле ввода поднято на правильную высоту (' + Math.round(distanceFromBottom) + 'px от низа)</div>';
addLog('Поле ввода поднято на правильную высоту', 'success', { distanceFromBottom: distanceFromBottom });
} else {
status.innerHTML += '<div class="status warning">⚠️ Поле ввода может быть слишком низко или высоко (' + Math.round(distanceFromBottom) + 'px от низа)</div>';
addLog('Поле ввода неправильно позиционировано', 'warning', { distanceFromBottom: distanceFromBottom });
}
}, 500);
});
}
} else {
status.innerHTML = '<div class="status warning">⚠️ AI Drawer не инициализирован</div>';
addLog('AI Drawer не инициализирован для теста клавиатуры', 'error');
}
} catch (error) {
status.innerHTML = '<div class="status warning">⚠️ Ошибка: ' + error.message + '</div>';
addLog('Ошибка в тесте клавиатуры', 'error', {
error: error.message,
stack: error.stack
});
}
}
// Тест 3: Размеры элементов
function testElementSizes() {
const status = document.getElementById('test3-status');
addLog('Начало теста: Размеры элементов', 'info');
try {
if (aiDrawerInstance) {
aiDrawerInstance.open();
addLog('AI Drawer открыт для теста размеров', 'info');
setTimeout(() => {
const input = document.querySelector('#ai-chat-input');
const button = document.querySelector('#ai-send-button');
const header = document.querySelector('.ai-drawer-header');
addLog('Проверка размеров элементов', 'debug', {
input: !!input,
button: !!button,
header: !!header
});
let results = [];
if (input) {
const inputRect = input.getBoundingClientRect();
const isInputSizeOK = inputRect.height >= 40 && inputRect.height <= 60;
results.push(isInputSizeOK ? '✅ Поле ввода: размер OK' : '⚠️ Поле ввода: размер может быть некорректным');
addLog('Размер поля ввода', isInputSizeOK ? 'success' : 'warning', {
height: inputRect.height,
expectedRange: '40-60px',
isOK: isInputSizeOK
});
}
if (button) {
const buttonRect = button.getBoundingClientRect();
const isButtonSizeOK = buttonRect.height >= 40 && buttonRect.height <= 60;
results.push(isButtonSizeOK ? '✅ Кнопка отправки: размер OK' : '⚠️ Кнопка отправки: размер может быть некорректным');
addLog('Размер кнопки отправки', isButtonSizeOK ? 'success' : 'warning', {
height: buttonRect.height,
expectedRange: '40-60px',
isOK: isButtonSizeOK
});
}
if (header) {
const headerRect = header.getBoundingClientRect();
const isHeaderSizeOK = headerRect.height >= 50 && headerRect.height <= 80;
results.push(isHeaderSizeOK ? '✅ Заголовок: размер OK' : '⚠️ Заголовок: размер может быть некорректным');
addLog('Размер заголовка', isHeaderSizeOK ? 'success' : 'warning', {
height: headerRect.height,
expectedRange: '50-80px',
isOK: isHeaderSizeOK
});
}
status.innerHTML = '<div class="status info">📏 Результаты проверки размеров:</div>' +
results.map(r => '<div class="status ' + (r.includes('✅') ? 'success' : 'warning') + '">' + r + '</div>').join('');
}, 500);
} else {
status.innerHTML = '<div class="status warning">⚠️ AI Drawer не инициализирован</div>';
addLog('AI Drawer не инициализирован для теста размеров', 'error');
}
} catch (error) {
status.innerHTML = '<div class="status warning">⚠️ Ошибка: ' + error.message + '</div>';
addLog('Ошибка в тесте размеров', 'error', {
error: error.message,
stack: error.stack
});
}
}
// Тест 4: Прокрутка
function testScrolling() {
const status = document.getElementById('test4-status');
addLog('Начало теста: Прокрутка и навигация', 'info');
try {
if (aiDrawerInstance) {
aiDrawerInstance.open();
addLog('AI Drawer открыт для теста прокрутки', 'info');
// Добавляем много сообщений для тестирования прокрутки
for (let i = 1; i <= 10; i++) {
aiDrawerInstance.addMessage(`Тестовое сообщение ${i} для проверки прокрутки`, i % 2 === 0);
}
addLog('Добавлено 10 тестовых сообщений', 'info');
setTimeout(() => {
const content = document.querySelector('.ai-drawer-content');
if (content) {
const canScroll = content.scrollHeight > content.clientHeight;
addLog('Проверка прокрутки', 'debug', {
scrollHeight: content.scrollHeight,
clientHeight: content.clientHeight,
canScroll: canScroll
});
if (canScroll) {
status.innerHTML = '<div class="status success">✅ Прокрутка работает корректно</div>';
addLog('Прокрутка работает корректно', 'success');
// Проверяем автоматическую прокрутку к последнему сообщению
const lastMessage = content.querySelector('.ai-message:last-child');
if (lastMessage) {
const lastMessageRect = lastMessage.getBoundingClientRect();
const contentRect = content.getBoundingClientRect();
const isLastMessageVisible = lastMessageRect.bottom <= contentRect.bottom;
addLog('Проверка автоматической прокрутки', 'debug', {
lastMessageRect: {
top: lastMessageRect.top,
bottom: lastMessageRect.bottom
},
contentRect: {
top: contentRect.top,
bottom: contentRect.bottom
},
isLastMessageVisible: isLastMessageVisible
});
if (isLastMessageVisible) {
status.innerHTML += '<div class="status success">✅ Автоматическая прокрутка к последнему сообщению работает</div>';
addLog('Автоматическая прокрутка работает', 'success');
} else {
status.innerHTML += '<div class="status warning">⚠️ Автоматическая прокрутка может работать некорректно</div>';
addLog('Автоматическая прокрутка работает некорректно', 'warning');
}
} else {
addLog('Последнее сообщение не найдено', 'warning');
}
} else {
status.innerHTML = '<div class="status warning">⚠️ Прокрутка может работать некорректно</div>';
addLog('Прокрутка работает некорректно', 'warning');
}
} else {
addLog('Контейнер контента не найден', 'error');
}
}, 500);
} else {
status.innerHTML = '<div class="status warning">⚠️ AI Drawer не инициализирован</div>';
addLog('AI Drawer не инициализирован для теста прокрутки', 'error');
}
} catch (error) {
status.innerHTML = '<div class="status warning">⚠️ Ошибка: ' + error.message + '</div>';
addLog('Ошибка в тесте прокрутки', 'error', {
error: error.message,
stack: error.stack
});
}
}
// Тест 5: Адаптивность
function testResponsiveness() {
const status = document.getElementById('test5-status');
addLog('Начало теста: Адаптивность интерфейса', 'info');
try {
if (aiDrawerInstance) {
aiDrawerInstance.open();
addLog('AI Drawer открыт для теста адаптивности', 'info');
setTimeout(() => {
const drawer = document.querySelector('.ai-drawer');
if (drawer) {
const rect = drawer.getBoundingClientRect();
const isResponsive = window.innerWidth <= 768 ?
rect.width >= window.innerWidth * 0.95 :
rect.width >= 350 && rect.width <= 450;
addLog('Проверка адаптивности', 'debug', {
drawerWidth: rect.width,
screenWidth: window.innerWidth,
isMobile: window.innerWidth <= 768,
isResponsive: isResponsive,
expectedRange: window.innerWidth <= 768 ?
`${window.innerWidth * 0.95}px+` :
'350-450px'
});
if (isResponsive) {
status.innerHTML = '<div class="status success">✅ Адаптивность работает корректно</div>';
addLog('Адаптивность работает корректно', 'success');
} else {
status.innerHTML = '<div class="status warning">⚠️ Адаптивность может работать некорректно</div>';
addLog('Адаптивность работает некорректно', 'warning');
}
// Проверяем медиа-запросы
const mediaQuery = window.matchMedia('(max-width: 768px)');
const isMobileQuery = mediaQuery.matches;
addLog('Проверка медиа-запросов', 'debug', {
mediaQuery: '(max-width: 768px)',
isActive: isMobileQuery,
screenWidth: window.innerWidth
});
status.innerHTML += '<div class="status info">📱 Медиа-запрос (max-width: 768px): ' + (isMobileQuery ? 'Активен' : 'Неактивен') + '</div>';
} else {
addLog('Drawer элемент не найден для теста адаптивности', 'error');
}
}, 500);
} else {
status.innerHTML = '<div class="status warning">⚠️ AI Drawer не инициализирован</div>';
addLog('AI Drawer не инициализирован для теста адаптивности', 'error');
}
} catch (error) {
status.innerHTML = '<div class="status warning">⚠️ Ошибка: ' + error.message + '</div>';
addLog('Ошибка в тесте адаптивности', 'error', {
error: error.message,
stack: error.stack
});
}
}
// Дополнительная информация для отладки
addLog('Тестовая страница загружена', 'info', {
screenSize: `${window.innerWidth}x${window.innerHeight}`,
isMobile: window.innerWidth <= 768,
userAgent: navigator.userAgent
});
// Проверяем статус сервера логов при загрузке
setTimeout(() => {
checkServerStatus();
}, 1000);
console.log('Mobile Keyboard Fix Test Page loaded');
console.log('Screen size:', window.innerWidth + 'x' + window.innerHeight);
console.log('Is mobile:', window.innerWidth <= 768);
</script>
</body>
</html>