Работа с файловыми загрузками

Файловые загрузки — одна из часто встречающихся задач в автоматизированном тестировании веб-приложений. В контексте Protractor работа с файлами отличается от стандартного взаимодействия с элементами страницы, так как браузеры не позволяют напрямую управлять нативными диалогами операционной системы. Решение этой задачи требует использования специальных приёмов и возможностей WebDriver.


Настройка окружения

Перед началом работы необходимо убедиться, что проект корректно настроен для работы с Protractor и Selenium WebDriver. Для работы с файловыми загрузками требуется:

  1. Protractor версии 7+ (с поддержкой Angular и не-Angular приложений).
  2. Node.js для выполнения скриптов и управления зависимостями.
  3. chromedriver или другой WebDriver, поддерживающий управление файловыми загрузками через sendKeys.

Файл protractor.conf.js должен содержать корректную конфигурацию браузера:

exports.config = {
    framework: 'jasmine',
    seleniumAddress: 'http://localhost:4444/wd/hub',
    specs: ['specs/fileUploadSpec.js'],
    capabilities: {
        browserName: 'chrome',
        chromeOptions: {
            prefs: {
                'download.default_directory': '/tmp/downloads',
                'download.prompt_for_download': false,
                'directory_upgrade': true
            }
        }
    },
    onPrepare: function() {
        browser.waitForAngularEnabled(false); // Для не-Angular страниц
    }
};

Ключевой момент — настройка chromeOptions.prefs. Здесь указывается директория для загрузки файлов и отключение диалогового окна подтверждения загрузки.


Работа с элементом загрузки файла

В HTML элемент <input type="file"> используется для загрузки файлов. Прямое взаимодействие с этим элементом в Protractor осуществляется через метод sendKeys(). Пример:

const path = require('path');

it('загружает файл на сервер', async () => {
    const fileToUpload = 'testFile.txt';
    const absolutePath = path.resolve(__dirname, fileToUpload);
    
    const fileInput = element(by.css('input[type="file"]'));
    await fileInput.sendKeys(absolutePath);
    
    const uploadButton = element(by.id('uploadButton'));
    await uploadButton.click();

    const successMessage = element(by.css('.upload-success'));
    expect(await successMessage.getText()).toContain('Файл загружен');
});

Особенности:

  • path.resolve используется для получения абсолютного пути к файлу, что необходимо для работы WebDriver.
  • Метод sendKeys() эмулирует выбор файла в диалоге без фактического открытия нативного окна.
  • После загрузки выполняется нажатие кнопки или другой механизм отправки формы.

Проверка загруженного файла

После успешной отправки файла полезно проверить:

  1. Появление уведомления на странице (.upload-success).
  2. Наличие файла в директории загрузок (для браузеров, которые позволяют доступ к локальной файловой системе через настройки).

Пример проверки с Node.js:

const fs = require('fs');
const downloadPath = '/tmp/downloads/testFile.txt';

it('проверяет наличие загруженного файла', async () => {
    const fileExists = fs.existsSync(downloadPath);
    expect(fileExists).toBe(true);
});

Автоматизация загрузки нескольких файлов

Для загрузки нескольких файлов необходимо передавать массив путей в sendKeys:

const files = [
    path.resolve(__dirname, 'file1.txt'),
    path.resolve(__dirname, 'file2.txt')
];

await element(by.css('input[type="file"]')).sendKeys(files.join('\n'));

Использование \n позволяет WebDriver корректно интерпретировать множественный выбор файлов.


Особенности работы с модальными диалогами

Если веб-приложение использует кастомные кнопки для открытия диалога выбора файла, прямое нажатие на них с click() не позволит выбрать файл, так как нативный диалог блокируется браузером. В таких случаях:

  • Прямой доступ к <input type="file"> через селектор является единственным надежным методом.
  • Если элемент скрыт стилями (display: none), его можно временно сделать видимым:
await browser.executeScript("arguments[0].style.display = 'block';", fileInput.getWebElement());
await fileInput.sendKeys(absolutePath);

После загрузки элемента можно вернуть исходное состояние стиля.


Загрузка файлов в не-Angular приложениях

Для сайтов без Angular важно отключить ожидание Angular:

browser.waitForAngularEnabled(false);

Без этого Protractor будет пытаться синхронизироваться с Angular, что приведет к ошибкам на обычных HTML-страницах с загрузкой файлов.


Практические рекомендации

  • Всегда использовать абсолютные пути к файлам. Относительные пути могут работать нестабильно на CI/CD серверах.
  • Проверять права доступа к директории загрузки, чтобы избежать ошибок Permission denied.
  • Для многоплатформенных тестов учитывать различия в пути к файлам между Windows и Linux.
  • При работе с множественными файлами проверять, что браузер поддерживает их одновременную отправку через sendKeys.

Работа с файловыми загрузками в Protractor сочетает использование стандартного WebDriver API с Node.js средствами работы с файлами. Грамотное управление элементами <input type="file">, настройка браузерных предпочтений и проверка загрузок позволяют создавать стабильные и надежные автотесты для сложных сценариев.