fix: письмо больше не попадает в вопрос скрининга — убран опасный fallback 'textarea' при наличии task_*, надёжный клик по переключателю письма, проверка ошибки валидации после отправки
This commit is contained in:
1 parent
6b2c7a0f09
commit
3179bac026
1 file changed
+36
-7
+36
-7
@@ -29,12 +29,13 @@ RESPONSE_BUTTONS = [
|
|||||||
]
|
]
|
||||||
# hh.ru прячет поле письма за переключателем «Сопроводительное письмо / Добавить»:
|
# hh.ru прячет поле письма за переключателем «Сопроводительное письмо / Добавить»:
|
||||||
# до клика по нему на форме есть только textarea вопроса скрининга (task_*).
|
# до клика по нему на форме есть только textarea вопроса скрининга (task_*).
|
||||||
|
# ВАЖНО: запасной селектор 'textarea' НЕ используется, если есть вопросы скрининга —
|
||||||
|
# иначе текст письма попадёт в первый вопрос вместо поля письма.
|
||||||
LETTER_TOGGLE = '[data-qa="vacancy-response-letter-toggle"]'
|
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-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',
|
|
||||||
]
|
]
|
||||||
SUBMIT_BUTTONS = [
|
SUBMIT_BUTTONS = [
|
||||||
'[data-qa="vacancy-response-submit-popup"]',
|
'[data-qa="vacancy-response-submit-popup"]',
|
||||||
@@ -272,18 +273,18 @@ def open_response_page(account_dir, user, account, vacancy, message,
|
|||||||
return False, "Не нашёл кнопку «Откликнуться» — проверьте скриншот", shot
|
return False, "Не нашёл кнопку «Откликнуться» — проверьте скриншот", shot
|
||||||
|
|
||||||
# Ждём модалку
|
# Ждём модалку
|
||||||
page.wait_for_timeout(2000)
|
page.wait_for_timeout(2500)
|
||||||
|
|
||||||
# hh.ru прячет поле письма за переключателем «Сопроводительное письмо» —
|
# hh.ru прячет поле письма за переключателем «Сопроводительное письмо» —
|
||||||
# раскрываем его, иначе заполнится textarea вопроса скрининга (task_*)
|
# раскрываем его, иначе заполнится textarea вопроса скрининга (task_*)
|
||||||
try:
|
try:
|
||||||
toggle = page.locator(LETTER_TOGGLE).first
|
toggle = page.locator(LETTER_TOGGLE).first
|
||||||
if toggle.is_visible(timeout=2000):
|
toggle.wait_for(state="visible", timeout=5000)
|
||||||
toggle.click()
|
toggle.click()
|
||||||
page.wait_for_timeout(800)
|
page.wait_for_timeout(800)
|
||||||
print(" ✓ Переключатель «Сопроводительное письмо» раскрыт")
|
print(" ✓ Переключатель «Сопроводительное письмо» раскрыт")
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
print(" ⚠ Переключатель письма не найден — поле может отсутствовать")
|
||||||
|
|
||||||
# Выбор резюме (радио-кнопка name="resumeId" value="{hash}")
|
# Выбор резюме (радио-кнопка name="resumeId" value="{hash}")
|
||||||
if resume_id:
|
if resume_id:
|
||||||
@@ -307,6 +308,19 @@ def open_response_page(account_dir, user, account, vacancy, message,
|
|||||||
except Exception:
|
except Exception:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
if not filled:
|
||||||
|
# Запасной вариант: если вопросов скрининга НЕТ, единственная
|
||||||
|
# textarea на форме — это поле письма (старая версия формы).
|
||||||
|
# При наличии task_* НЕ заполняем — иначе письмо попадёт в вопрос.
|
||||||
|
try:
|
||||||
|
if page.locator('textarea[name^="task_"]').count() == 0:
|
||||||
|
field = page.locator('textarea').first
|
||||||
|
if field.is_visible(timeout=2000):
|
||||||
|
field.fill(message)
|
||||||
|
filled = True
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
if not filled:
|
if not filled:
|
||||||
shot = _save_screenshot(page, screenshot_dir, vacancy["id"])
|
shot = _save_screenshot(page, screenshot_dir, vacancy["id"])
|
||||||
return False, "Не нашёл поле сообщения — проверьте скриншот", shot
|
return False, "Не нашёл поле сообщения — проверьте скриншот", shot
|
||||||
@@ -336,7 +350,22 @@ def open_response_page(account_dir, user, account, vacancy, message,
|
|||||||
# ловим любые ошибки, но отклик уже отправлен.
|
# ловим любые ошибки, но отклик уже отправлен.
|
||||||
try:
|
try:
|
||||||
page.wait_for_timeout(2500)
|
page.wait_for_timeout(2500)
|
||||||
|
# Проверяем, не осталась ли форма открытой с ошибкой валидации
|
||||||
|
# (например, не заполнены обязательные вопросы скрининга)
|
||||||
|
form_open = page.locator('[data-qa="vacancy-response-popup-form"]').count()
|
||||||
|
err_visible = False
|
||||||
|
if form_open:
|
||||||
|
for sel in ['[data-qa="vacancy-response-error"]',
|
||||||
|
'[data-qa="vacancy-response-popup-form"] [class*="error"]']:
|
||||||
|
try:
|
||||||
|
if page.locator(sel).first.is_visible(timeout=1000):
|
||||||
|
err_visible = True
|
||||||
|
break
|
||||||
|
except Exception:
|
||||||
|
continue
|
||||||
shot = _save_screenshot(page, screenshot_dir, vacancy["id"])
|
shot = _save_screenshot(page, screenshot_dir, vacancy["id"])
|
||||||
|
if form_open and err_visible:
|
||||||
|
return False, "hh.ru не принял отклик — проверьте скриншот (возможно, не заполнены обязательные вопросы)", shot
|
||||||
except Exception:
|
except Exception:
|
||||||
shot = None
|
shot = None
|
||||||
return True, "Отклик отправлен", shot
|
return True, "Отклик отправлен", shot
|
||||||
|
|||||||
Reference in new issue
Block a user