fix: hh.ru прячет поле письма за переключателем — клик по vacancy-response-letter-toggle, новый селектор письма и кнопки отправки; фронтенд больше не показывает успех при ok=false

This commit is contained in:
apuc committed 2026-09-22 11:11:13 +03:00
1 parent bd8d865798
commit d757d2f8c7
2 files changed
+24 -2

No files matched your search

+16
View File
@@ -27,12 +27,17 @@ RESPONSE_BUTTONS = [
'[data-qa="vacancy-response-link"]', '[data-qa="vacancy-response-link"]',
'button:has-text("Откликнуться")', 'button:has-text("Откликнуться")',
] ]
# hh.ru прячет поле письма за переключателем «Сопроводительное письмо / Добавить»:
# до клика по нему на форме есть только textarea вопроса скрининга (task_*).
LETTER_TOGGLE = '[data-qa="vacancy-response-letter-toggle"]'
MESSAGE_FIELDS = [ MESSAGE_FIELDS = [
'textarea[data-qa="vacancy-response-popup-form-letter-input"]',
'textarea[data-qa="vacancy-response-letter"]', 'textarea[data-qa="vacancy-response-letter"]',
'textarea[data-qa="vacancy-response-popup-form"] textarea', 'textarea[data-qa="vacancy-response-popup-form"] textarea',
'textarea', 'textarea',
] ]
SUBMIT_BUTTONS = [ SUBMIT_BUTTONS = [
'[data-qa="vacancy-response-submit-popup"]',
'[data-qa="vacancy-response-submit"]', '[data-qa="vacancy-response-submit"]',
'[data-qa="vacancy-response-popup-form"] button[type="submit"]', '[data-qa="vacancy-response-popup-form"] button[type="submit"]',
'button:has-text("Отправить")', 'button:has-text("Отправить")',
@@ -265,6 +270,17 @@ def open_response_page(account_dir, user, account, vacancy, message,
# Ждём модалку # Ждём модалку
page.wait_for_timeout(2000) page.wait_for_timeout(2000)
# hh.ru прячет поле письма за переключателем «Сопроводительное письмо» —
# раскрываем его, иначе заполнится textarea вопроса скрининга (task_*)
try:
toggle = page.locator(LETTER_TOGGLE).first
if toggle.is_visible(timeout=2000):
toggle.click()
page.wait_for_timeout(800)
print(" ✓ Переключатель «Сопроводительное письмо» раскрыт")
except Exception:
pass
# Выбор резюме (радио-кнопка name="resumeId" value="{hash}") # Выбор резюме (радио-кнопка name="resumeId" value="{hash}")
if resume_id: if resume_id:
try: try:
+8 -2
View File
@@ -677,7 +677,7 @@ async function sendFromModal() {
const data = await api(`/api/accounts/${currentAccount}/send-now`, { const data = await api(`/api/accounts/${currentAccount}/send-now`, {
method: 'POST', body: JSON.stringify({ id: sendModalId, message }), method: 'POST', body: JSON.stringify({ id: sendModalId, message }),
}); });
if (data.screenshot) { if (data.ok && data.screenshot) {
showShotModal(sendModalId, data.screenshot, data.note || 'Отклик отправлен', true); showShotModal(sendModalId, data.screenshot, data.note || 'Отклик отправлен', true);
sentTexts.add(sendModalId); sentTexts.add(sendModalId);
const v = vacancies.find(x => x.id === sendModalId); const v = vacancies.find(x => x.id === sendModalId);
@@ -685,6 +685,10 @@ async function sendFromModal() {
renderVacancies(); renderVacancies();
renderTexts(); renderTexts();
closeSendModal(); closeSendModal();
} else if (data.screenshot) {
// Бэкенд вернул скриншот, но отклик НЕ отправлен (например, не нашёл поле)
showShotModal(sendModalId, data.screenshot, data.note || 'Не удалось отправить отклик', false);
btn.disabled = false;
} else { } else {
note.textContent = data.note || 'Не удалось отправить отклик'; note.textContent = data.note || 'Не удалось отправить отклик';
btn.disabled = false; btn.disabled = false;
@@ -737,13 +741,15 @@ async function sendVacancy(id) {
method: 'POST', body: JSON.stringify({ id, message }), method: 'POST', body: JSON.stringify({ id, message }),
}); });
if (note) note.textContent = data.note || ''; if (note) note.textContent = data.note || '';
if (data.screenshot) { if (data.ok && data.screenshot) {
showShotModal(id, data.screenshot, data.note || 'Отклик отправлен', true); showShotModal(id, data.screenshot, data.note || 'Отклик отправлен', true);
sentTexts.add(id); sentTexts.add(id);
const v = vacancies.find(x => x.id === id); const v = vacancies.find(x => x.id === id);
if (v) v.responded = true; if (v) v.responded = true;
renderVacancies(); renderVacancies();
renderTexts(); renderTexts();
} else if (data.screenshot) {
showShotModal(id, data.screenshot, data.note || 'Не удалось отправить отклик', false);
} else { } else {
alert(data.note || 'Не удалось отправить отклик'); alert(data.note || 'Не удалось отправить отклик');
} }