cypressでCSVダウンロードをテストする


まとめ

cypressの公式リポジトリーに例があるからそちらを参照するとできる。

日本語の記事が検索に引っかからなかったから、記事を書いてみました。
エイリアス的な感じですね。

要点

  • cypressにはブラウザのダウンロード機能をハックする仕組みがあり、ダウンロードディレクトリをDownloadsから変えることができる。つまりローカルに持ってこれる。
  • ローカルに持ってきたCSVファイルをneatCSVでパースしてオブジェクト化する。
  • テストする。

cypressはブラウザのダウンロードAPIをハックする以外にもいろんな事ができる

実際に書いてみてあると便利なコマンド

以下の3つのコマンドを用意しているとテストしやすいかなって考えます。

コマンド 説明
allowDownloadPopup ダウンロードポップアップを自動でYESにするcypressコマンド
readCSV csvファイルを読み込んでパースしてオブジェクト化するcypressコマンド
detectEncoding csvファイルを読み込んでエンコーディングを調べるcypressコマンド
const path = require('path');
const neatCSV = require('neat-csv');
const encoding = require('encoding-japanese');

const defaultDownloadFolder = 'cypress/downloads';

export function allowDownloadPopup(downloadPath, options) {
  // The next command allow downloads in Electron, Chrome, and Edge
  // without any users popups or file save dialogs.
  if (Cypress.browser.name !== 'firefox') {
    // since this call returns a promise, must tell Cypress to wait
    // for it to be resolved
    cy.wrap(
      Cypress.automation('remote:debugger:protocol', {
        command: 'Page.setDownloadBehavior',
        params: { behavior: 'allow', downloadPath: downloadPath || defaultDownloadFolder },
      }),
      { log: false, ...options },
    );
  }
}

export function readCSV(filename, downloadFolder = defaultDownloadFolder, options = {}) {
  const filepath = path.join(downloadFolder, filename);
  return cy.readFile(filepath, { timeout: 15000, ...options }).then(neatCSV);
}

export function detectEncoding(filename, downloadFolder = defaultDownloadFolder, options = {}) {
  const filepath = path.join(downloadFolder, filename);
  return cy
    .readFile(filepath, { timeout: 1500, ...options })
    .then((data, options) => encoding.detect(data));
}

使い方

allowDownloadPopup

beforeEach(function(){
 cy.allowDownloadPopup()
})

readCSV

test.csv を読み込んで、レコード数と最初のレコードの内容をテストする。

test.csv
a,b,c
1,2,3
cy.get('button').contains('CSV(UTF-8))').click()
cy.readCSV('test.csv')
  .then(list => {
     expect(list, 'number of records').to.have.length(1)
     expect(list[0], 'first record').to.deep.equal({
	a: 1,
	b: 2,
	c: 3
     })
  })

detectEncoding

test.csv を読み込んで、エンコーディングが UTF-8 であることをテストする。

cy.detectEncoding('test.csv').then(encoding => {
   expect(encoding, 'encoding').to.equal('UTF-8')
})

以上です。