How can I upload a file in Playwright when the input element has the `hidden` attribute?

I’m trying to use page.setInputFiles() in Playwright to upload a file, but the input element I’m targeting is hidden.

My code looks like this:

await page.locator('//div/input[@class="xyz"]').setInputFiles('Upload_files/CSV Test file.csv');

However, Playwright fails to find the locator because the <input> element has the hidden attribute:

<input type="file" class="xyz" accept=".jpg,.jpeg,.png,.doc,.docx,.xlsx,.xls,.csv,.pdf" hidden>

What’s the right way to handle file uploads in Playwright when the file input is hidden or not directly visible in the DOM?

@alveera.khn Unlike Selenium, Playwright doesn’t require the input to be visible, it can upload to hidden elements directly.

Just ensure you’re targeting the correct selector and the file path exists:

await page.setInputFiles('input[type="file"].xyz', 'Upload_files/CSV Test file.csv');

Why it works:

setInputFiles() doesn’t depend on the visibility of the element.

The only common issue is an incorrect selector, make sure your locator points directly to the and not its wrapper.

If the hidden input is only created or made visible after clicking an upload button, first trigger the event and then set the file:

const [fileChooser] = await Promise.all([
  page.waitForEvent('filechooser'),
  page.click('button:has-text("Upload")'), // or the element that opens the file dialog
]);
await fileChooser.setFiles('Upload_files/CSV Test file.csv');

Why it works: Some apps open hidden fields dynamically through JavaScript when clicking an upload button.

Waiting for the filechooser event ensures Playwright attaches to that input at the right time.

If the app’s framework strictly blocks access to hidden elements (e.g., React input validation), you can temporarily unhide the input, upload the file, and hide it again:

const input = page.locator('input[type="file"].xyz');
await page.evaluate(el => el.removeAttribute('hidden'), await input.elementHandle());
await input.setInputFiles('Upload_files/CSV Test file.csv');
await page.evaluate(el => el.setAttribute('hidden', ''), await input.elementHandle());

You’re momentarily making the element visible so that frameworks relying on the DOM state don’t reject the file assignment.