fff
This commit is contained in:
@@ -443,3 +443,193 @@ class BrowserService:
|
||||
except Exception as e:
|
||||
logging.error(f"❌ Ошибка при выборе вкладки по индексу {tab_index}: {e}")
|
||||
return False
|
||||
|
||||
def select_tab_by_multiple_methods(self, tab_text, timeout=15):
|
||||
"""Пытается выбрать вкладку на странице перебором всех элементов.
|
||||
|
||||
Args:
|
||||
tab_text (str): Текст вкладки для поиска
|
||||
timeout (int): Общее время ожидания в секундах
|
||||
|
||||
Returns:
|
||||
bool: True, если вкладка найдена и выбрана, иначе False
|
||||
"""
|
||||
end_time = time.time() + timeout
|
||||
attempt = 0
|
||||
|
||||
# Нормализуем текст для поиска
|
||||
tab_text_normalized = tab_text.strip()
|
||||
tab_text_lower = tab_text_normalized.lower()
|
||||
|
||||
logging.info(f"🔍 Начинаю поиск вкладки: '{tab_text}'")
|
||||
|
||||
while time.time() < end_time:
|
||||
attempt += 1
|
||||
logging.info(f" Попытка {attempt}: перебираю все элементы на странице...")
|
||||
|
||||
try:
|
||||
# Ищем и кликаем через JavaScript в одном скрипте
|
||||
script = """
|
||||
var searchText = arguments[0].toLowerCase();
|
||||
var allElements = document.querySelectorAll('*');
|
||||
var foundElements = [];
|
||||
|
||||
console.log('Ищу элемент с текстом:', searchText);
|
||||
|
||||
for (var i = 0; i < allElements.length; i++) {
|
||||
var el = allElements[i];
|
||||
var elementText = el.textContent || el.innerText || '';
|
||||
var visibleText = elementText.trim();
|
||||
|
||||
// Проверяем только прямой текст элемента (не включая детей)
|
||||
var directText = '';
|
||||
for (var j = 0; j < el.childNodes.length; j++) {
|
||||
if (el.childNodes[j].nodeType === 3) { // TEXT_NODE
|
||||
directText += el.childNodes[j].nodeValue;
|
||||
}
|
||||
}
|
||||
directText = directText.trim();
|
||||
|
||||
// Совпадение по прямому тексту или полному тексту
|
||||
var match = false;
|
||||
if (directText.toLowerCase() === searchText ||
|
||||
visibleText.toLowerCase() === searchText) {
|
||||
match = true;
|
||||
} else if (directText.toLowerCase().includes(searchText) ||
|
||||
visibleText.toLowerCase().includes(searchText)) {
|
||||
match = true;
|
||||
}
|
||||
|
||||
if (match) {
|
||||
// Проверяем видимость элемента
|
||||
var rect = el.getBoundingClientRect();
|
||||
var style = window.getComputedStyle(el);
|
||||
|
||||
if (rect.width > 0 && rect.height > 0 &&
|
||||
style.display !== 'none' &&
|
||||
style.visibility !== 'hidden' &&
|
||||
style.opacity !== '0') {
|
||||
foundElements.push({
|
||||
element: el,
|
||||
tag: el.tagName.toLowerCase(),
|
||||
text: visibleText.substring(0, 50),
|
||||
directText: directText.substring(0, 50)
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.log('Найдено элементов:', foundElements.length);
|
||||
|
||||
// Пытаемся кликнуть на каждый найденный элемент
|
||||
for (var k = 0; k < foundElements.length; k++) {
|
||||
var item = foundElements[k];
|
||||
var elem = item.element;
|
||||
|
||||
try {
|
||||
// Прокручиваем к элементу (без анимации для скорости)
|
||||
elem.scrollIntoView({block: 'center', behavior: 'auto'});
|
||||
|
||||
// Небольшая пауза для стабильности (выполняется синхронно)
|
||||
var startWait = Date.now();
|
||||
while (Date.now() - startWait < 200) {
|
||||
// Ждем 200мс
|
||||
}
|
||||
|
||||
console.log('Пробую кликнуть элемент:', item.tag, item.text);
|
||||
|
||||
// Сначала находим САМЫЙ кликабельный элемент в иерархии
|
||||
var targetToClick = elem;
|
||||
|
||||
// Ищем родителя который является ссылкой или кнопкой
|
||||
var clickableParent = elem.closest('a, button, [role="tab"], [role="button"], li');
|
||||
if (clickableParent) {
|
||||
console.log('Найден кликабельный родитель:', clickableParent.tagName, clickableParent.className);
|
||||
targetToClick = clickableParent;
|
||||
}
|
||||
|
||||
// Теперь пробуем все методы клика на найденном элементе
|
||||
var methods = [
|
||||
{
|
||||
name: 'direct click',
|
||||
fn: function(el) { el.click(); }
|
||||
},
|
||||
{
|
||||
name: 'mousedown+mouseup',
|
||||
fn: function(el) {
|
||||
el.dispatchEvent(new MouseEvent('mousedown', {bubbles: true, cancelable: true}));
|
||||
el.dispatchEvent(new MouseEvent('mouseup', {bubbles: true, cancelable: true}));
|
||||
el.dispatchEvent(new MouseEvent('click', {bubbles: true, cancelable: true}));
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'dispatchEvent click',
|
||||
fn: function(el) {
|
||||
el.dispatchEvent(new MouseEvent('click', {
|
||||
view: window,
|
||||
bubbles: true,
|
||||
cancelable: true,
|
||||
clientX: el.getBoundingClientRect().left + 5,
|
||||
clientY: el.getBoundingClientRect().top + 5
|
||||
}));
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'focus + click',
|
||||
fn: function(el) {
|
||||
if (el.focus) el.focus();
|
||||
el.click();
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
// Пробуем каждый метод
|
||||
for (var m = 0; m < methods.length; m++) {
|
||||
try {
|
||||
console.log('Пробую метод:', methods[m].name, 'на', targetToClick.tagName);
|
||||
methods[m].fn(targetToClick);
|
||||
console.log('✅ Успешно кликнул методом:', methods[m].name);
|
||||
return {success: true, tag: targetToClick.tagName, text: item.text, method: methods[m].name};
|
||||
} catch(err) {
|
||||
console.log('✗ Метод', methods[m].name, 'не сработал:', err.message);
|
||||
}
|
||||
}
|
||||
|
||||
} catch(err) {
|
||||
console.log('Общая ошибка при обработке элемента:', err.message);
|
||||
}
|
||||
}
|
||||
|
||||
return {success: false, found: foundElements.length, message: 'Элементы найдены, но ни один метод клика не сработал'};
|
||||
"""
|
||||
|
||||
result = self.driver.execute_script(script, tab_text_lower)
|
||||
|
||||
if result and isinstance(result, dict):
|
||||
if result.get('success'):
|
||||
method = result.get('method', 'unknown')
|
||||
tag = result.get('tag', 'unknown')
|
||||
text = result.get('text', '')
|
||||
logging.info(f" ✅ УСПЕХ! Метод: {method}, тег: <{tag}>, текст: '{text}'")
|
||||
time.sleep(0.5)
|
||||
return True
|
||||
else:
|
||||
found_count = result.get('found', 0)
|
||||
message = result.get('message', 'Не найдено')
|
||||
if found_count > 0:
|
||||
logging.warning(f" ✗ Попытка {attempt}: найдено {found_count} элементов, но кликнуть не удалось")
|
||||
else:
|
||||
logging.warning(f" ✗ Попытка {attempt}: {message}")
|
||||
else:
|
||||
logging.warning(f" ✗ Попытка {attempt}: некорректный результат от JavaScript")
|
||||
|
||||
time.sleep(1)
|
||||
|
||||
except Exception as e:
|
||||
logging.warning(f" ✗ Ошибка при попытке {attempt}: {e}")
|
||||
import traceback
|
||||
logging.debug(traceback.format_exc())
|
||||
time.sleep(1)
|
||||
|
||||
logging.error(f"❌ Не удалось найти и кликнуть на вкладку '{tab_text}' за {timeout} секунд после {attempt} попыток")
|
||||
return False
|
||||
Reference in New Issue
Block a user