Playwrightでテスト失敗(Fail)時に画面キャプチャと動画を撮ってSlackに投稿する

Playwrightでテスト失敗(Fail)時に画面キャプチャと動画を撮ってSlackに投稿する

PlaywrightのE2Eテスト失敗時のSlackへの通知機能を拡張し、スクリーンショットと動画も自動投稿できるように実装する方法を解説します。設定ファイルの変更とカスタムレイアウトの作成で実現可能です。
Clock Icon2024.12.07

情報システム室の進地@日比谷です。

Playwrightでテスト失敗(Fail)時にSlack投稿する方法として、以前、次の記事を書きました。

GitHub ActionsでPlaywright E2Eテストを定期実行し、結果をSlack通知する

失敗が通知されたその後にデバッグすることを考えると、失敗時の画面キャプチャやそこに至るまでの画面遷移の動画があるととても助かります。そこで、Slackにて失敗を通知する際に、画面キャプチャと動画も投稿する方法をご案内します。

失敗(Fail)時の画面キャプチャ、動画作成を有効化する

Playwrightには標準機能で画面キャプチャと動画作成を行う機能があります。

Trace viewer | Playwright
Videos | Playwright

具体的にはplaywright.config.tsにて、下記の記述を行います。

export default defineConfig({
  :
  use: {
    // 下記の3行を追加する //
    trace: 'retain-on-failure',
    screenshot: { mode: 'only-on-failure', fullPage: true },
    video: "retain-on-failure",
  },
  :
});

これでエラー発生時に画面キャプチャと動画が生成されます(例ではtraceも有効化しています)。

Slackにて生成した画面キャプチャと動画を投稿する

プロジェクトルートに次のコードをcustom_layout.tsとして作成します。

import fs from 'fs';
import path from 'path';
import { Block, KnownBlock } from '@slack/types';
import { SummaryResults } from 'playwright-slack-report/dist/src';
import { WebClient } from '@slack/web-api';
import FormData from 'form-data';

const web = new WebClient(process.env.SLACK_BOT_USER_OAUTH_TOKEN);

async function uploadFileToSlack(filePath: string, filename: string, channelId: string): Promise<string | undefined> {
  try {
    // ファイルを読み込む
    const fileContent = fs.readFileSync(filePath);

    // ファイルをアップロード
    const result = await web.files.uploadV2({
      channel_id: channelId,
      filename: filename,
      file: fileContent,
    });

    // アップロードされたファイルの情報を取得
    return result.files[0].files[0].permalink;
  } catch (error) {
    console.error('Error uploading file:', error);
    return undefined;
  }
}

export async function generateCustomLayoutAsync(
  summaryResults: SummaryResults,
): Promise<Array<KnownBlock | Block>> {
  const { tests } = summaryResults;
  // create your custom slack blocks

  const header = {
    type: 'header',
    text: {
      type: 'plain_text',
      text: '🎭 *新締処理 E2E Test Results*',
      emoji: true,
    },
  };

  const summary = {
    type: 'section',
    text: {
      type: 'mrkdwn',
      text: `✅ *${summaryResults.passed}* | ❌ *${summaryResults.failed}* | ⏩ *${summaryResults.skipped}*`,
    },
  };

  const fails: Array<KnownBlock | Block> = [];

  for (const t of tests) {
    if (t.status === 'failed' || t.status === 'timedOut') {
      fails.push({
        type: 'section',
        text: {
          type: 'mrkdwn',
          text: `👎 *[${t.browser}] | ${t.suiteName.replace(/\W/gi, '-')}*`,
        },
      });

      const assets: Array<string> = [];

      if (t.attachments) {
        for (const a of t.attachments) {
          const filePath = a.path;
          const fileName = path.basename(filePath);

          // ファイルをSlackにアップロード
          const permalink = await uploadFileToSlack(filePath, fileName, process.env.SLACK_NOTIFY_CHANNEL_ID_ARTIFACTS);

          if (permalink) {
            let icon = '';
            if (a.name === 'screenshot') {
              icon = '📸';
            } else if (a.name === 'video') {
              icon = '🎥';
            }

            assets.push(`${icon}  See the <${permalink}|${a.name}>`);
          }
        }
      }

      if (assets.length > 0) {
        fails.push({
          type: 'context',
          elements: [{ type: 'mrkdwn', text: assets.join('\n') }],
        });
      }
    }
  }

  return [header, summary, { type: 'divider' }, ...fails];
}

このコードはplaywright-slack-reportで紹介されているサンプルをベースにカスタマイズしています。サンプルはAWS S3にスナップショットと動画をアップロードしてリンクする形になっていますが、このコードではSlackにアップロードしてリンクする形にしています。

次に、必要なモジュールをインストールします。

$ npm i @slack/web-api
$ npm i form-data

最後に、playwright.config.tsにカスタムレイアウトを使用する記述を追加します。

:
// カスタムレイアウトをimportする
import { generateCustomLayoutAsync } from './custom_layout';
:
export default defineConfig({
  :
  reporter: [
    [
      "./node_modules/playwright-slack-report/dist/src/SlackReporter.js",
      {
        :
        // 次の1行を追加
        layoutAsync: generateCustomLayoutAsync,
      },
    ],
  ],
  :
});

必要な環境変数の値をGitHubのsecretsに登録し、GitHub Actionsのワークフローで環境変数に設定する記述を行えば完成です。記述の仕方はこちらのコードを参考にしてください。

実行結果

次の画像のような形で、テスト実行の結果がSlack通知されます。

E2ESlack通知実行サンプルサマリー

screenshotやvideoのリンクをクリックすると次の画像のように表示されます。

E2ESlack通知実行サンプル詳細

なお、通知本体(サマリー)と画面キャプチャや動画を投稿するチャンネルは分けています。
これは、投稿をまとめやすいというメリットと同時に、本体側のチャンネルにファイルが無尽蔵に増えて見通しが悪くなることを回避できるメリットがあります。

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.