Мы используем npm xlsx
для создания xlsx-документа, содержащего данные, представленные в представлении React. Мы хотим реализовать тест Cypress UI, который проверяет, что данные экспортируются правильно, путем загрузки сгенерированного файла, его открытия и подтверждения его содержимого. Тест выполняется в нашем конвейере CI - это означает, что он работает в автономном режиме (и с использованием electron
браузера).
Вот как мы генерируем данные:
import XLSX from "xlsx";
export function createXlsx(data, sheetName, fileName) {
const workSheet = XLSX.utils.aoa_to_sheet(data);
const workBook = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(workBook, workSheet, sheetName);
XLSX.writeFile(workBook, fileName);
}
Когда пользователь щелкает " Экспорт », данные передаются в метод createXlsx
, и пользователю предлагается диалоговое окно сохранения.
Для части Cypress мы следовали учебному руководству *, имея следующую настройку в plugins/index.js
:
on('before:browser:launch', (browser = {}, launchOptions) => {
const downloadDirectory = path.join(process.cwd(), config.env.testDownloadsDirectory);
if (browser.family === 'chromium') {
if (launchOptions.preferences.default) {
launchOptions.preferences.default['download'] = { default_directory: downloadDirectory };
}
}
return launchOptions;
});
on('task', {
parseXlsx({ filePath }) {
return new Promise((resolve, reject) => {
try {
const workBook = xlsx.readFile(filePath);
const data = xlsx.utils.sheet_to_json(workBook.Sheets.Data);
resolve(data);
} catch (e) {
reject(e);
}
});
}
});
... и тест:
...
cy.get('button[data-cy="export"]').click();
cy.readFile(filePath, 'binary', { log: true, timeout: 5000 })
.should('exist');
cy.task('parseXlsx', { filePath })
.then(data => {
// assertions here
});
...
Все это прекрасно работает при локальном запуске с --headed --browser chrome
- файл сохраняется, затем загружается и утверждается.
Это не работает при выполнении тестов --headless
(* this - , упомянутых в комментариях под руководством).
Поскольку я относительно новичок в JavaScript / React, мне интересно, если это можно было сделать как-нибудь. Во-первых, я не совсем понимаю, как XLSX.writeFile(...)
заставляет браузер открывать диалог сохранения и можно ли к нему подключиться.
Еще одна идея, которая у меня возникла, заключалась в том, чтобы создать обычную конечную точку React (с собственным URI, например, /#/xlsx-export
), который сгенерирует файл, поэтому я мог бы попытаться вызвать http.get(...)
из зарегистрированного обработчика событий задачи Cypress, но поскольку это все еще приложение React, я подозреваю, что это не будет иметь никакого значения. (Этот подход также не позволяет мне выполнять манипуляции с данными до того, как я нажму кнопку экспорта)