Функция playwright's set_input_files() не работает должным образом в python

Я пишу тесты для своего Django-проекта, используя playwright и StaticLiveServerTestCase. В одном тесте мне нужно выбрать два файла с помощью поля input[type=file] и отправить их на сервер.

file_input = page.locator('input[type="file"]')
file_input.set_input_files(["Input1.xlsx", "Input2.xlsx"])

Но Playwright отправляет только первый файл, и мой тест не удается. Я пытался посмотреть, имеет ли поле ввода только один файл, но после выбора

оно имеет оба файла.
file_info = page.evaluate("""
            element => {
                const files = Array.from(element.files);
                return files.map(file => ({
                    name: file.name,
                    size: file.size,
                    type: file.type
                }));
            }
        """, file_input.element_handle())
print("Files that JS sees:", file_info)

Вот вывод:

Files that JS sees: [{'name': 'Input1.xlsx', 'size': 5853, 'type': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'}, {'name': 'Input2.xlsx', 'size': 5851, 'type': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'}]

А Драматург выводит только первого:

input_value = file_input.input_value()
print("Playwright's version:", input_value)

Playwright's version: C:\fakepath\Input1.xlsx

Если вы спросите меня, я пробовал абсолютный путь для файлов и пытался изменить браузеры.

Django версии 5.1.6 Playwright версии 1.51.0

Первое, что нужно сказать, это то, что вам нужно сравнить яблоки с яблоками. В вашем page.evaluate вы получаете доступ к свойству files, но в file_input.input_value() вы получаете доступ к свойству value.

Это разные свойства элемента HTMLInputElement

Итак, вместо file_input.input_value() вам нужно что-то вроде file_input.get_property('files'), но, к сожалению, этого нет в API Playground (AFAIK).

Единственный способ, которым я мог это сделать, - использовать устаревший element handle API, вот мой тест на Javascript (извините, я давно не использовал python).

Я использую страницу, предоставленную MDN, для запуска своего теста.

Метод evaluate() ограничен возвратом простых значений, но свойство input.files возвращает объект FileList, который не может быть возвращен неповрежденным, поэтому мы необходимо извлечь данные, которые нам нужны для утверждения в функции evaluate.

test('file upload', async ({ page }) => {

  await page.goto('https://mdn.github.io/learning-area/html/forms/file-examples/simple-file.html');

  const fileInput = page.locator('input[type="file"]');
  await fileInput.setInputFiles(['./fixtures/Input1.xlsx', './fixtures/Input2.xlsx']);

  // for reference, this is the input value 
  await expect(fileInput).toHaveValue('C:\\fakepath\\Input1.xlsx');

  // evaluate the input files property
  const inputHandle = await page.waitForSelector('input[type="file"]');
  const file0 = await inputHandle.evaluate(input => {
    return (input as HTMLInputElement).files!.item(0)!.name;
  });
  expect(file0).toBe('Input1.xlsx');

  const file1 = await inputHandle.evaluate(input => {
    return (input as HTMLInputElement).files!.item(1)!.name;
  });
  expect(file1).toBe('Input2.xlsx')

}) 

Этот тест выполнен успешно, что означает, что к файлу действительно прикреплены два файла. <input>.

enter image description here

Проблема была на стороне сервера. Я забыл создать пользователя для тестирования, потому что тестовая система создает пустую базу данных, поэтому в хранилище у меня был только один файл.

Вернуться на верх