Fix resume upload targeting wrong file input on Ashby

Prefer resume-specific file inputs (#resume, #_systemfield_resume)
over autofill inputs. Skip autofill class inputs in fallback.
Also fix Ashby beforeSubmit to target #_systemfield_resume directly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-06 21:15:16 -08:00
parent 0118254046
commit fa6efc3775
2 changed files with 13 additions and 9 deletions

View File

@@ -15,15 +15,14 @@ export async function apply(page, job, formFiller) {
verifySelector: '#_systemfield_name', verifySelector: '#_systemfield_name',
beforeSubmit: async (page, formFiller) => { beforeSubmit: async (page, formFiller) => {
if (!formFiller.profile.resume_path) return; if (!formFiller.profile.resume_path) return;
// Ashby wraps resume upload in a custom component — find the actual file input // #_systemfield_resume IS the file input (not a container)
const fileInput = await page.$('#_systemfield_resume input[type="file"]') || const fileInput = await page.$('input[type="file"]#_systemfield_resume') ||
await page.$('input[type="file"][name*="resume"]') ||
await page.$('input[type="file"]'); await page.$('input[type="file"]');
if (fileInput) { if (fileInput) {
const hasFile = await fileInput.evaluate(el => !!el.value); const hasFile = await fileInput.evaluate(el => !!el.value);
if (!hasFile) { if (!hasFile) {
await fileInput.setInputFiles(formFiller.profile.resume_path).catch(() => {}); await fileInput.setInputFiles(formFiller.profile.resume_path).catch(() => {});
await page.waitForTimeout(1500); await page.waitForTimeout(2000);
} }
} }
}, },

View File

@@ -573,12 +573,17 @@ Answer:`;
const radios = await container.$$('input[type="radio"][aria-label*="resume"], input[type="radio"][aria-label*="Resume"]'); const radios = await container.$$('input[type="radio"][aria-label*="resume"], input[type="radio"][aria-label*="Resume"]');
if (radios[0]) await radios[0].click().catch(() => {}); if (radios[0]) await radios[0].click().catch(() => {});
} else if (snap.resumeRadios.length === 0 && snap.hasFileInput && resumePath) { } else if (snap.resumeRadios.length === 0 && snap.hasFileInput && resumePath) {
const fileInput = await container.$('input[type="file"]'); // Prefer resume-specific file inputs, skip autofill inputs
if (fileInput) { const fileInput = await container.$('input[type="file"]#resume') ||
// Skip if the file input doesn't accept our resume format (e.g. image-only uploads) await container.$('input[type="file"]#_systemfield_resume') ||
const accept = await fileInput.getAttribute('accept').catch(() => '') || ''; await container.$('input[type="file"][id*="resume" i]') ||
await container.$('input[type="file"][name*="resume" i]');
// Fallback to first non-autofill file input
const target = fileInput || await container.$('input[type="file"]:not([class*="autofill"])');
if (target) {
const accept = await target.getAttribute('accept').catch(() => '') || '';
const acceptsResume = !accept || /pdf|doc|docx/i.test(accept); const acceptsResume = !accept || /pdf|doc|docx/i.test(accept);
if (acceptsResume) await fileInput.setInputFiles(resumePath).catch(() => {}); if (acceptsResume) await target.setInputFiles(resumePath).catch(() => {});
} }
} }