feat: complete try coding
This commit is contained in:
parent
6243ccb470
commit
17c1d971d4
1 changed files with 119 additions and 37 deletions
156
script.js
156
script.js
|
|
@ -60,6 +60,37 @@
|
|||
return false;
|
||||
}
|
||||
|
||||
function findCodingQuiz() {
|
||||
const quizzes = document.querySelectorAll('section.quiz_type_coding');
|
||||
for (const quiz of quizzes) {
|
||||
if (handledQuizzes.has(quiz)) continue;
|
||||
if (quiz.classList.contains('quiz_answered')) { handledQuizzes.add(quiz); continue; }
|
||||
const runBtn = quiz.querySelector('button.quiz__coding-footer-action-button');
|
||||
if (!runBtn) { handledQuizzes.add(quiz); continue; }
|
||||
if (quiz.offsetParent !== null) return quiz;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
async function handleCodingQuiz(quiz) {
|
||||
console.log('💻 Квиз с кодом — запускаем...');
|
||||
const runBtn = quiz.querySelector('button.quiz__coding-footer-action-button');
|
||||
runBtn.click();
|
||||
|
||||
// Ждём пока квиз пометится как решённый
|
||||
const startTime = Date.now();
|
||||
while (Date.now() - startTime < 60000) {
|
||||
await sleep(CHECK_INTERVAL);
|
||||
if (quiz.classList.contains('quiz_answered') || !quiz.querySelector('button.quiz__coding-footer-action-button')) {
|
||||
console.log('✓ Код выполнен');
|
||||
break;
|
||||
}
|
||||
}
|
||||
handledQuizzes.add(quiz);
|
||||
await sleep(CLICK_DELAY);
|
||||
return true;
|
||||
}
|
||||
|
||||
function findQuizForm() {
|
||||
const forms = document.querySelectorAll(QUIZ_FORM_SELECTOR);
|
||||
for (const form of forms) {
|
||||
|
|
@ -184,11 +215,20 @@
|
|||
async function handleQuizForm(form) {
|
||||
console.log('❓ Квиз...');
|
||||
|
||||
const firstRadio = form.querySelector('input[type="radio"]');
|
||||
if (firstRadio) {
|
||||
firstRadio.click();
|
||||
console.log('✓ Выбран первый вариант');
|
||||
await sleep(300);
|
||||
const checkboxes = form.querySelectorAll('input[type="checkbox"]');
|
||||
if (checkboxes.length > 0) {
|
||||
for (const cb of checkboxes) {
|
||||
if (!cb.checked) cb.click();
|
||||
await sleep(100);
|
||||
}
|
||||
console.log(`✓ Выбраны все чекбоксы (${checkboxes.length})`);
|
||||
} else {
|
||||
const firstRadio = form.querySelector('input[type="radio"]');
|
||||
if (firstRadio) {
|
||||
firstRadio.click();
|
||||
console.log('✓ Выбран первый вариант');
|
||||
await sleep(300);
|
||||
}
|
||||
}
|
||||
|
||||
const submitBtn = form.querySelector(QUIZ_SUBMIT_SELECTOR);
|
||||
|
|
@ -228,6 +268,9 @@
|
|||
while (Date.now() - startTime < timeout) {
|
||||
if (!isRunning) return null;
|
||||
|
||||
const codingQuiz = findCodingQuiz();
|
||||
if (codingQuiz) return { type: 'coding', element: codingQuiz };
|
||||
|
||||
const quiz = findQuizForm();
|
||||
if (quiz) return { type: 'quiz', element: quiz };
|
||||
|
||||
|
|
@ -248,6 +291,14 @@
|
|||
|
||||
async function processLesson() {
|
||||
while (isRunning) {
|
||||
let codingQuiz = findCodingQuiz();
|
||||
if (codingQuiz) {
|
||||
scrollToElement(codingQuiz);
|
||||
await sleep(300);
|
||||
await handleCodingQuiz(codingQuiz);
|
||||
continue;
|
||||
}
|
||||
|
||||
let quiz = findQuizForm();
|
||||
if (quiz) {
|
||||
scrollToElement(quiz);
|
||||
|
|
@ -280,6 +331,13 @@
|
|||
return null;
|
||||
}
|
||||
|
||||
if (result.type === 'coding') {
|
||||
scrollToElement(result.element);
|
||||
await sleep(300);
|
||||
await handleCodingQuiz(result.element);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (result.type === 'quiz') {
|
||||
scrollToElement(result.element);
|
||||
await sleep(300);
|
||||
|
|
@ -331,6 +389,7 @@
|
|||
break;
|
||||
}
|
||||
|
||||
await sleep(1000);
|
||||
scrollToElement(nextLessonBtn);
|
||||
await sleep(300);
|
||||
nextLessonBtn.click();
|
||||
|
|
@ -451,32 +510,35 @@
|
|||
}
|
||||
|
||||
async function handleTrainerPage() {
|
||||
console.log('💡 Загружаем исходник страницы для поиска решения...');
|
||||
const answerPanes = await fetchAnswerPanes();
|
||||
if (!document.querySelector('button.trainer-footer__solution-button')) {
|
||||
console.log('💡 Загружаем исходник страницы для поиска решения...');
|
||||
const answerPanes = await fetchAnswerPanes();
|
||||
|
||||
if (!answerPanes || answerPanes.length === 0) {
|
||||
console.log('ℹ️ Авторского решения нет для этой задачи');
|
||||
return false;
|
||||
}
|
||||
if (!answerPanes || answerPanes.length === 0) {
|
||||
console.log('ℹ️ Авторского решения нет для этой задачи');
|
||||
return false;
|
||||
}
|
||||
|
||||
const solution = answerPanes[0].content;
|
||||
if (!solution) {
|
||||
console.log('ℹ️ Контент решения пустой');
|
||||
return false;
|
||||
}
|
||||
const solution = answerPanes[0].content;
|
||||
if (!solution) {
|
||||
console.log('ℹ️ Контент решения пустой');
|
||||
return false;
|
||||
}
|
||||
|
||||
console.log(`💡 Найдено решение (${answerPanes[0].name}), вставляем...`);
|
||||
insertSolutionIntoMonaco(solution);
|
||||
console.log(`💡 Найдено решение (${answerPanes[0].name}), вставляем...`);
|
||||
insertSolutionIntoMonaco(solution);
|
||||
await sleep(CLICK_DELAY);
|
||||
|
||||
await sleep(CLICK_DELAY);
|
||||
|
||||
const checkBtn = document.querySelector('button.trainer-footer__check-button');
|
||||
if (checkBtn) {
|
||||
checkBtn.click();
|
||||
console.log('✅ Нажата кнопка "Проверить", ждём результата...');
|
||||
const checkBtn = document.querySelector('button.trainer-footer__check-button');
|
||||
if (checkBtn) {
|
||||
checkBtn.click();
|
||||
console.log('✅ Нажата кнопка "Проверить", ждём результата...');
|
||||
} else {
|
||||
console.log('⚠️ Кнопка "Проверить" не найдена');
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
console.log('⚠️ Кнопка "Проверить" не найдена');
|
||||
return true;
|
||||
console.log('ℹ️ Задача уже решена');
|
||||
}
|
||||
|
||||
// Ждём кнопку "Далее" без ограничения по времени
|
||||
|
|
@ -495,21 +557,41 @@
|
|||
return true;
|
||||
}
|
||||
|
||||
async function dispatch() {
|
||||
// Сброс состояния при каждом вызове
|
||||
isRunning = true;
|
||||
clickedButtons = new WeakSet();
|
||||
handledQuizzes = new WeakSet();
|
||||
handledFeedbacks = new WeakSet();
|
||||
|
||||
const path = window.location.pathname;
|
||||
console.log(`🔄 Страница: ${path}`);
|
||||
|
||||
if (path.includes('/profile/associated-programs-android-st-v2')) {
|
||||
const found = handleAssociatedProgramsPage();
|
||||
if (found) await handleCourseModal();
|
||||
} else if (path.includes('/trainer/') && window.monaco?.editor.getEditors().length > 0) {
|
||||
await handleTrainerPage();
|
||||
} else if (path.includes('/trainer/') || path.includes('/topics/')) {
|
||||
await run();
|
||||
}
|
||||
}
|
||||
|
||||
// Перехват SPA-навигации
|
||||
const _pushState = history.pushState.bind(history);
|
||||
history.pushState = function(...args) {
|
||||
_pushState(...args);
|
||||
setTimeout(() => dispatch(), PAGE_LOAD_DELAY);
|
||||
};
|
||||
window.addEventListener('popstate', () => {
|
||||
setTimeout(() => dispatch(), PAGE_LOAD_DELAY);
|
||||
});
|
||||
|
||||
window.stopAutoClick = function() {
|
||||
isRunning = false;
|
||||
console.log('⏹ Остановлено');
|
||||
};
|
||||
|
||||
console.log('💡 Для остановки: stopAutoClick()');
|
||||
|
||||
if (window.location.pathname.includes('/profile/associated-programs-android-st-v2')) {
|
||||
const found = handleAssociatedProgramsPage();
|
||||
if (found) {
|
||||
await handleCourseModal();
|
||||
}
|
||||
} else if (window.location.pathname.includes('/trainer/') && window.monaco?.editor.getEditors().length > 0) {
|
||||
await handleTrainerPage();
|
||||
} else {
|
||||
run();
|
||||
}
|
||||
await dispatch();
|
||||
})();
|
||||
Loading…
Add table
Reference in a new issue