(function autoClickSequential() { // Настройки const CLICK_DELAY = 800; const CHECK_INTERVAL = 500; const MAX_WAIT_TIME = 5000; const PAGE_LOAD_DELAY = 2000; // Селекторы const BUTTON_SELECTOR = 'button.content-expander__button'; const NEXT_LESSON_SELECTOR = 'button[data-test-id="next-lesson-control-button"]'; const FEEDBACK_FORM_SELECTOR = 'section.quiz_type_feedback'; const FEEDBACK_NEXT_SELECTOR = 'button.quiz__move-on'; const FEEDBACK_TEXTAREA_SELECTOR = 'textarea.input__control'; const QUIZ_FORM_SELECTOR = 'form.quiz_type_select'; const QUIZ_SUBMIT_SELECTOR = 'button.quiz__submit'; let clickCount = 0; let lessonCount = 0; let isRunning = true; let clickedButtons = new WeakSet(); let handledQuizzes = new WeakSet(); let handledFeedbacks = new WeakSet(); function findNewButton() { const buttons = document.querySelectorAll(BUTTON_SELECTOR); for (const button of buttons) { if (clickedButtons.has(button)) continue; if (button.offsetParent !== null) { return button; } } return null; } function findNextLessonButton() { const button = document.querySelector(NEXT_LESSON_SELECTOR); if (button && button.offsetParent !== null) { return button; } return null; } function findFeedbackForm() { const forms = document.querySelectorAll(FEEDBACK_FORM_SELECTOR); for (const form of forms) { if (handledFeedbacks.has(form)) continue; if (form.offsetParent !== null) { return form; } } return null; } function isQuizAnswered(form) { const checkedRadio = form.querySelector('input[type="radio"][aria-checked="true"]'); if (checkedRadio) return true; if (form.classList.contains('quiz_answered')) return true; const submitBtn = form.querySelector(QUIZ_SUBMIT_SELECTOR); if (!submitBtn) return true; return false; } function findQuizForm() { const forms = document.querySelectorAll(QUIZ_FORM_SELECTOR); for (const form of forms) { if (handledQuizzes.has(form)) continue; if (isQuizAnswered(form)) { handledQuizzes.add(form); continue; } if (form.offsetParent !== null) { return form; } } return null; } // Симуляция нативного ввода текста function simulateTyping(textarea, text) { textarea.focus(); // Устанавливаем значение через нативный setter const nativeInputValueSetter = Object.getOwnPropertyDescriptor( window.HTMLTextAreaElement.prototype, 'value' ).set; nativeInputValueSetter.call(textarea, text); // Триггерим все возможные события textarea.dispatchEvent(new Event('input', { bubbles: true, cancelable: true })); textarea.dispatchEvent(new Event('change', { bubbles: true, cancelable: true })); textarea.dispatchEvent(new KeyboardEvent('keydown', { bubbles: true })); textarea.dispatchEvent(new KeyboardEvent('keyup', { bubbles: true })); textarea.dispatchEvent(new KeyboardEvent('keypress', { bubbles: true })); // React-specific события const reactEvent = new Event('input', { bubbles: true }); reactEvent.simulated = true; textarea.dispatchEvent(reactEvent); } async function handleFeedbackForm(form) { console.log('📝 Форма обратной связи...'); // Проверяем, есть ли текстовое поле const textarea = form.querySelector(FEEDBACK_TEXTAREA_SELECTOR); if (textarea) { // Симулируем ввод текста simulateTyping(textarea, 'СПАСИБО!'); console.log('✓ Введён текст "СПАСИБО!"'); await sleep(500); // Пробуем ещё раз если кнопка всё ещё disabled let nextBtn = form.querySelector(FEEDBACK_NEXT_SELECTOR); if (nextBtn && nextBtn.disabled) { // Ещё один способ - через React fiber const reactKey = Object.keys(textarea).find(key => key.startsWith('__reactFiber') || key.startsWith('__reactProps')); if (reactKey) { const reactProps = textarea[reactKey]; if (reactProps && reactProps.onChange) { reactProps.onChange({ target: textarea }); } } await sleep(300); } } else { // Обрабатываем radio-кнопки const radioGroups = form.querySelectorAll('.likert-scale__statement-row'); for (const row of radioGroups) { const firstRadio = row.querySelector('input[type="radio"]'); if (firstRadio && !firstRadio.checked) { firstRadio.click(); await sleep(100); } } console.log('✓ Выбраны ответы "да"'); } await sleep(300); // Ждём пока кнопка станет активной let nextBtn = form.querySelector(FEEDBACK_NEXT_SELECTOR); let attempts = 0; while (nextBtn && nextBtn.disabled && attempts < 15) { await sleep(200); nextBtn = form.querySelector(FEEDBACK_NEXT_SELECTOR); attempts++; } if (nextBtn && !nextBtn.disabled) { nextBtn.click(); console.log('✓ Нажата кнопка "Далее"'); handledFeedbacks.add(form); await sleep(CLICK_DELAY); return true; } // Если кнопка всё ещё disabled, пробуем кликнуть принудительно if (nextBtn) { console.log('⚠️ Кнопка disabled, пробуем принудительный клик...'); nextBtn.disabled = false; nextBtn.classList.remove('button2_disabled'); nextBtn.click(); handledFeedbacks.add(form); await sleep(CLICK_DELAY); return true; } handledFeedbacks.add(form); return false; } async function handleQuizForm(form) { console.log('❓ Квиз...'); const firstRadio = form.querySelector('input[type="radio"]'); if (firstRadio) { firstRadio.click(); console.log('✓ Выбран первый вариант'); await sleep(300); } const submitBtn = form.querySelector(QUIZ_SUBMIT_SELECTOR); if (submitBtn && !submitBtn.disabled) { submitBtn.click(); console.log('✓ Нажата кнопка "Узнать ответ"'); handledQuizzes.add(form); await sleep(CLICK_DELAY); return true; } await sleep(200); const submitBtnRetry = form.querySelector(QUIZ_SUBMIT_SELECTOR); if (submitBtnRetry && !submitBtnRetry.disabled) { submitBtnRetry.click(); console.log('✓ Нажата кнопка "Узнать ответ"'); handledQuizzes.add(form); await sleep(CLICK_DELAY); return true; } handledQuizzes.add(form); return false; } function scrollToElement(element) { element.scrollIntoView({ behavior: 'smooth', block: 'center' }); } function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } async function waitForElement(timeout = MAX_WAIT_TIME) { const startTime = Date.now(); while (Date.now() - startTime < timeout) { if (!isRunning) return null; const quiz = findQuizForm(); if (quiz) return { type: 'quiz', element: quiz }; const feedback = findFeedbackForm(); if (feedback) return { type: 'feedback', element: feedback }; const nextLesson = findNextLessonButton(); if (nextLesson) return { type: 'next', button: nextLesson }; const button = findNewButton(); if (button) return { type: 'expander', button: button }; await sleep(CHECK_INTERVAL); } return null; } async function processLesson() { while (isRunning) { let quiz = findQuizForm(); if (quiz) { scrollToElement(quiz); await sleep(300); await handleQuizForm(quiz); continue; } let feedback = findFeedbackForm(); if (feedback) { scrollToElement(feedback); await sleep(300); await handleFeedbackForm(feedback); continue; } let nextLesson = findNextLessonButton(); if (nextLesson) { return nextLesson; } let button = findNewButton(); if (!button) { console.log('⏳ Ожидание...'); const result = await waitForElement(); if (!result) { console.log('🏁 Элементов больше нет'); return null; } if (result.type === 'quiz') { scrollToElement(result.element); await sleep(300); await handleQuizForm(result.element); continue; } if (result.type === 'feedback') { scrollToElement(result.element); await sleep(300); await handleFeedbackForm(result.element); continue; } if (result.type === 'next') { return result.button; } button = result.button; } scrollToElement(button); await sleep(300); clickedButtons.add(button); const buttonText = button.textContent.trim(); button.click(); clickCount++; console.log(`✓ [${clickCount}] Нажата: "${buttonText}"`); await sleep(CLICK_DELAY); } return null; } async function run() { console.log('🚀 Запуск...'); while (isRunning) { lessonCount++; console.log(`📖 Урок ${lessonCount}`); const nextLessonBtn = await processLesson(); if (!nextLessonBtn) { console.log('🏁 Уроки закончились'); break; } scrollToElement(nextLessonBtn); await sleep(300); nextLessonBtn.click(); console.log('➡️ Переход к следующему уроку...'); await sleep(PAGE_LOAD_DELAY); clickedButtons = new WeakSet(); handledQuizzes = new WeakSet(); handledFeedbacks = new WeakSet(); } console.log(`\n✅ Готово!`); console.log(`📊 Уроков пройдено: ${lessonCount}`); console.log(`🖱️ Кнопок нажато: ${clickCount}`); } window.stopAutoClick = function() { isRunning = false; console.log('⏹ Остановлено'); }; console.log('💡 Для остановки: stopAutoClick()'); run(); })();