This commit is contained in:
MasterAkulon 2025-12-06 11:58:24 +03:00
commit cc3e2c1b10

345
script.js Normal file
View file

@ -0,0 +1,345 @@
(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();
})();