fix: always discard on modal dismiss, support "Continue applying" button
- dismissModal now always waits for Discard confirmation after closing (previously returned early after Dismiss click, leaving draft saved) - LINKEDIN_APPLY_BUTTON_SELECTOR matches both "Easy Apply" and "Continue applying" (shown when a previous draft exists) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -267,39 +267,37 @@ export async function apply(page, job, formFiller) {
|
||||
* All searches use page.$() which pierces shadow DOM.
|
||||
*/
|
||||
async function dismissModal(page, modalSelector) {
|
||||
// Try aria-label Dismiss
|
||||
// Step 1: Close the modal — Dismiss button, Close/X, or Escape
|
||||
const dismissBtn = await page.$(`${modalSelector} button[aria-label="Dismiss"]`);
|
||||
if (dismissBtn) {
|
||||
await dismissBtn.click({ timeout: DISMISS_TIMEOUT }).catch(() => {});
|
||||
return;
|
||||
} else {
|
||||
const closeBtn = await page.$(`${modalSelector} button[aria-label="Close"], ${modalSelector} button[aria-label*="close"]`);
|
||||
if (closeBtn) {
|
||||
await closeBtn.click({ timeout: DISMISS_TIMEOUT }).catch(() => {});
|
||||
} else {
|
||||
await page.keyboard.press('Escape').catch(() => {});
|
||||
}
|
||||
}
|
||||
|
||||
// Try close/X button
|
||||
const closeBtn = await page.$(`${modalSelector} button[aria-label="Close"], ${modalSelector} button[aria-label*="close"]`);
|
||||
if (closeBtn) {
|
||||
await closeBtn.click({ timeout: DISMISS_TIMEOUT }).catch(() => {});
|
||||
return;
|
||||
}
|
||||
|
||||
// Fallback: Escape key
|
||||
await page.keyboard.press('Escape').catch(() => {});
|
||||
|
||||
// Handle "Discard" confirmation dialog that may appear after Escape
|
||||
// Step 2: LinkedIn shows a "Discard" confirmation — always wait for it and click
|
||||
const discardBtn = await page.waitForSelector(
|
||||
'button[data-test-dialog-primary-btn]',
|
||||
{ timeout: DISMISS_TIMEOUT, state: 'visible' }
|
||||
).catch(() => null);
|
||||
if (discardBtn) {
|
||||
await discardBtn.click().catch(() => {});
|
||||
await page.waitForTimeout(500);
|
||||
return;
|
||||
}
|
||||
|
||||
// Last resort: find Discard by text — scan all buttons via page.$$()
|
||||
// Fallback: find Discard by text — scan all buttons via page.$$()
|
||||
const allBtns = await page.$$('button');
|
||||
for (const btn of allBtns) {
|
||||
const text = await btn.evaluate(el => (el.innerText || '').trim().toLowerCase()).catch(() => '');
|
||||
if (text === 'discard') {
|
||||
await btn.click().catch(() => {});
|
||||
await page.waitForTimeout(500);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ export const APPLY_BETWEEN_DELAY_JITTER = 1000;
|
||||
// --- LinkedIn ---
|
||||
export const LINKEDIN_BASE = 'https://www.linkedin.com';
|
||||
export const LINKEDIN_EASY_APPLY_MODAL_SELECTOR = '[role="dialog"]';
|
||||
export const LINKEDIN_APPLY_BUTTON_SELECTOR = '[aria-label*="Easy Apply"]';
|
||||
export const LINKEDIN_APPLY_BUTTON_SELECTOR = '[aria-label*="Easy Apply"], [aria-label*="Continue applying"]';
|
||||
export const LINKEDIN_MAX_MODAL_STEPS = 20;
|
||||
|
||||
// --- Wellfound ---
|
||||
|
||||
Reference in New Issue
Block a user