Блог
Автотесты/Playwright

Upload и download файлов в Playwright

Загрузка и скачивание файлов в Playwright — две операции, которые автоматизируются через API браузера, а не через реальное взаимодействие с системным диалогом ОС: для загрузки файл подставляется программно в элемент <input type="file"> через setInputFiles, а для скачивания Playwright перехватывает событие download на объекте page. Оба механизма работают, минуя нативные окна операционной системы, которыми обычные веб-локаторы не управляют.

Как загрузить файл на страницу в Playwright?

await page.locator('input[type="file"]').setInputFiles('./fixtures/resume.pdf');

setInputFiles устанавливает файл прямо в элемент <input type="file">, минуя системный диалог выбора файла ОС — путь к файлу передаётся программно, а не выбирается кликами в файловом менеджере. Это работает даже если сам <input> визуально скрыт (display: none или opacity: 0), что часто встречается на реальных сайтах, где кастомная кнопка «Загрузить файл» перекрывает нативный, некрасивый input.

Как загрузить несколько файлов или файл прямо из памяти?

await page.locator('input[type="file"]').setInputFiles([
'./fixtures/photo1.jpg',
'./fixtures/photo2.jpg',
]);

await page.locator('input[type="file"]').setInputFiles({
name: 'generated.txt',
mimeType: 'text/plain',
buffer: Buffer.from('Содержимое файла прямо из теста'),
});

Если у input установлен атрибут multiple, setInputFiles принимает массив путей и загружает все файлы одним вызовом. Второй способ — передать объект с name/mimeType/buffer вместо реального пути на диске: это создаёт файл «на лету» прямо в памяти теста, без необходимости заранее готовить физический файл-фикстуру на диске — удобно для генерируемых данных или когда важно протестировать конкретное содержимое файла.

Как скачать файл и поймать событие download в Playwright?

const [download] = await Promise.all([
page.waitForEvent('download'),
page.getByRole('link', { name: 'Скачать отчёт' }).click(),
]);

await download.saveAs('./downloads/report.pdf');
console.log(await download.path());

Клик по ссылке или кнопке скачивания в браузере запускает скачивание асинхронно — Playwright перехватывает это как событие download на объекте page. Promise.all здесь необходим: клик и ожидание события должны запуститься практически одновременно, потому что событие download может сработать очень быстро после клика, и если сначала дождаться завершения клика, а потом начать слушать событие — есть риск пропустить его. download.saveAs() сохраняет скачанный файл в нужное место, а download.path() возвращает путь к временному файлу, где Playwright уже сохранил скачанное содержимое автоматически (независимо от saveAs).

Как проверить содержимое скачанного файла?

const [download] = await Promise.all([
page.waitForEvent('download'),
page.getByRole('link', { name: 'Скачать отчёт' }).click(),
]);
const path = await download.path();
const content = fs.readFileSync(path, 'utf-8');
expect(content).toContain('Итоговый отчёт');

После получения объекта download и пути к сохранённому файлу тест может прочитать содержимое файла обычными средствами Node.js (fs.readFileSync) и проверить его — например, что CSV-экспорт содержит нужные строки, а не просто что файл вообще скачался. Это особенно важно для тестов экспорта данных, где сам факт скачивания файла — не полная проверка: файл может скачаться пустым или с неправильными данными, и без проверки содержимого такой баг не найдётся.

Какие методы и события для файлов стоит запомнить?

— `setInputFiles(path)`. Загружает один файл в <input type="file">, минуя диалог ОС. Пример: setInputFiles('./fixtures/resume.pdf').
— `setInputFiles([path1, path2])`. Загружает несколько файлов одним вызовом (нужен атрибут multiple). Пример: setInputFiles(['photo1.jpg', 'photo2.jpg']).
— `setInputFiles({ name, mimeType, buffer })`. Создаёт файл «на лету» в памяти теста без физического файла на диске. Пример: buffer: Buffer.from('...').
— `page.waitForEvent('download')`. Перехватывает событие скачивания, запущенное кликом. Пример: Promise.all([page.waitForEvent('download'), ...]).
— `download.saveAs(path)`. Сохраняет скачанный файл в указанное место. Пример: download.saveAs('./downloads/report.pdf').
— `download.path()`. Возвращает путь к временному файлу, где Playwright уже сохранил содержимое. Пример: await download.path().
— `download.suggestedFilename()`. Возвращает имя файла из заголовка Content-Disposition сервера. Пример: download.suggestedFilename().
Этот список — не полный перечень API Playwright для работы с файлами, а только методы и события, которые пригождаются чаще всего: загрузка одного или нескольких файлов, создание файла в памяти, перехват скачивания и проверка результата.

Частые вопросы про загрузку и скачивание файлов в Playwright

Нужно ли настраивать что-то особое в браузере для скачивания файлов в тестах? Нет, Playwright по умолчанию перехватывает скачивания через API, не полагаясь на настройки браузера для скачивания в конкретную папку — событие download срабатывает независимо от того, куда браузер обычно сохраняет файлы у реального пользователя.
Можно ли протестировать сам системный диалог выбора файла ОС? Нет, и не нужно — Playwright (как и большинство инструментов автоматизации браузера) не может управлять нативными диалогами операционной системы, потому что они не являются частью веб-страницы. Есть два официальных способа обойти диалог, а не один: setInputFiles напрямую на элемент <input>, и событие page.on('filechooser') / fileChooser.setFiles() — им перехватывают момент, когда клик по кастомной кнопке асинхронно должен открыть диалог выбора файла, и подставляют файл программно вместо реального диалога ОС.
Что делать, если файл нужно перетащить (drag-and-drop) в зону загрузки, а не через input? Если зона загрузки реализована через drag-and-drop API без обычного <input type="file">, setInputFiles может не сработать напрямую — тогда используют page.dispatchEvent с эмуляцией нужных drag-событий (dragenter, dragover, drop) с DataTransfer, содержащим файл, что заметно сложнее, чем обычный setInputFiles. Часто в таких зонах загрузки скрытый <input type="file"> всё равно присутствует в DOM для доступности — тогда проще найти именно его.
Как проверить, что после скачивания файл имеет правильное имя? У объекта download есть метод suggestedFilename(), который возвращает имя файла, предложенное сервером (обычно из заголовка Content-Disposition) — можно сверить его с ожидаемым значением через expect(download.suggestedFilename()).toBe('report.pdf'), не дожидаясь сохранения самого файла на диск.

Закрепить загрузку и скачивание файлов на практике

Race condition с Promise.all для скачивания — одна из тех ошибок, которую проще один раз увидеть на собственном тесте, чем поверить на слово. Потренироваться на реальных сценариях загрузки и скачивания файлов можно на бесплатном тренажёре Playwright Arena от Quality Academy — 30 задач в трёх модулях, бесплатно и без ограничения попыток.

-------

Полезные ссылки школы

Сайт Quality Academy:
/main
Telegram-канал:
https://t.me/quality_academy
YouTube-канал:
https://www.youtube.com/@quality_academy
ВКонтакте:
https://vk.com/quality_academy
Канал отзывов учеников (58+ отзывов):
https://t.me/quality_academy_reviews
Задать вопрос менеджеру:
https://t.me/quality_academy_bot
Тест «Подойдёт ли вам тестирование»:
https://quiz.quality-academy.ru
5000+ вопросов с собесов тестировщика — бот-тренажёр:
https://t.me/quality_academy_interview_bot
3 практические задачи и дорожная карта:
https://t.me/quality_academy_tasks_bot
Бесплатные тренажёры — SQL Arena, Playwright Arena, Python Arena:
SQL Arena · Playwright Arena · Python Arena