From 029360b118914061c6174595673afd7c86c752ec Mon Sep 17 00:00:00 2001 From: Matthew Jackson Date: Fri, 6 Mar 2026 14:54:40 -0800 Subject: [PATCH] Dismiss LinkedIn education/experience sub-forms before filling LinkedIn sometimes opens an Add Education/Experience sub-form with Save/Cancel buttons that blocks the main Next button. Detect and cancel these before attempting to fill the step. Co-Authored-By: Claude Opus 4.6 --- lib/apply/easy_apply.mjs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/lib/apply/easy_apply.mjs b/lib/apply/easy_apply.mjs index 9fbc990..16b3b04 100644 --- a/lib/apply/easy_apply.mjs +++ b/lib/apply/easy_apply.mjs @@ -189,6 +189,16 @@ export async function apply(page, job, formFiller) { const debugInfo = await getModalDebugInfo(page, MODAL); console.log(` [step ${step}] progress=${progress} heading="${debugInfo.heading}" buttons=${JSON.stringify(debugInfo.buttons)}${debugInfo.errors.length ? ' errors=' + JSON.stringify(debugInfo.errors) : ''}`); + // LinkedIn sometimes opens an "Add education/experience" sub-form with Save/Cancel buttons. + // These block the main Next button. Dismiss them before filling. + const saveBtn = await findModalButton(page, MODAL, { ariaLabels: [], exactTexts: ['Save'] }); + const cancelBtn = await findModalButton(page, MODAL, { ariaLabels: [], exactTexts: ['Cancel'] }); + if (saveBtn && cancelBtn) { + console.log(` [step ${step}] sub-form detected (Save/Cancel) — cancelling`); + await cancelBtn.click({ timeout: APPLY_CLICK_TIMEOUT }).catch(() => {}); + await page.waitForTimeout(CLICK_WAIT); + } + // Fill form fields — page.$() in form_filler pierces shadow DOM const unknowns = await formFiller.fill(page, formFiller.profile.resume_path); if (unknowns.length > 0) console.log(` [step ${step}] unknown fields: ${JSON.stringify(unknowns.map(u => u.label || u))}`);