📑

【Playwright】S3から取得したファイルでアップロードをテストする

2 min read

この記事はGAOGAO Advent Calendar 2021 ことしもGAOGAOまつりです の7日目の記事です。
昨日の記事は、【PHP】docx, xlsx, pptxのテキストを取得するでした。

はじめに

こんにちは。今月から神戸に移住したしまむらです。
世界中でモノつくりの連鎖を起こすスタートアップスタジオGAOGAOでソフトウェアエンジニアをしています。

1週間アドベントカレンダーを乗っ取った関係で、本日も私がお送りいたします。

チーム内で同じファイルをテストに使用する場合、、S3に保存しているファイルを用いれば、わざわざローカルにファイルを保持しておく必要がなくなります。

必要な流れを簡潔にまとめてみました。

※ローカル環境での実行を想定しています。

事前条件

  • Playwright 1.15.2
  • AWS SDK for JavaScriptでの最低限の設定は完了済み(S3にアクセス権限のあるIAMユーザ等で)
  • 取得したいファイルがS3バケットに存在する

やること

  • S3からファイルを取得(GetObjectCommand)
  • 取得したファイルをサーバに書き込む
  • setInputFiles()にファイルをセットする
  • アップロード処理後は、サーバからファイルを削除する

1. S3からファイルのオブジェクトを取得

sample.ts
import { S3Client, GetObjectCommand } from "@aws-sdk/client-s3"
import * as fs from 'fs'
import { Readable } from 'stream'
...

// some codes...

test('file upload', async () => {
    // some codes...
    const client = new S3Client({})
    const command = new GetObjectCommand({
        Bucket: '<バケット>', // バケット名
	Key: '<キー名>' // 例)バケット直下にtest.txtがある場合はtest.txt
    })
    const { Body } = await client.send(command)

2. 実行サーバにファイルを書き込み

temp以下に書き込みストリームを作成し、パイプ処理を実行。

sample.ts
const writer: fs.WriteStream = fs.createWriteStream('temp/test.txt')
if (Body instanceof Readable) { // tsの場合これが必要
    Body.pipe(writer)
}

3. 書き込んだファイルをinputにセット

sample.ts
const handle = await page.$('input[type="file"]')
await handle.setInputFiles(`temp/test.txt`)

// フォームのPOST処理などを実行

setInputFiles()で添付したファイルを実際にフォーム等で送信する処理が続くと思います。

4. 実行サーバからファイルを削除する

temp以下に書き込んだファイルをお掃除します。

sample.ts
// アップロードが完了後
fs.unlinkSync('temp/test.txt')

以上が、S3にあるテスト用のファイルをアップロードテストする流れになります。
実際に添付したファイルの扱いに関してはこの記事では触れません🙇‍♂️

補足(ハマったところ)

SDKのGetObjectCommand()の返り値(GetObjectCommandOutput)には、ドキュメントによると Readable, ReadableStream, Blobの3つがあるそうです。Readable型ではない場合はpipe処理が実行できないので、if文で型を指定しています。
※typescriptで実装する場合はそのままだとエラーとなります。

https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/clients/client-s3/interfaces/getobjectcommandoutput.html#body

以上、S3からテストファイルを取得してアップロードをテストする例でした。
どなたかの参考になれば幸いです。

Discussion

ログインするとコメントできます