Playwrightに入門しました

2023-08-28

概要

  • Playwrightを今週触り始めた初心者です。
  • ダークモードなどアプリのテーマ対応のテストに使えるかなと思い触りました。
  • 使い始めて気がついた点をメモしました。

結論

  • 各種のブラウザ操作を表示又は非表示で、コードから操作し、テストやテスト以外のことに使える。
  • テストを実行するにはコードが必要であるが、ブラウザを操作すると操作履歴がコードに落ちるのでテストを迅速に開発するのに役立てることができる。
  • とはいえ、色々ノウハウが必要そうである。今回最初に気がついた点をいくつかメモします。

Playwright Testとは?

  • Playwright Testは、エンドツーエンドテストのニーズに対応するために特別に作成されました。
  • Playwrightは、Chromium、WebKit、Firefoxを含むすべての最新のレンダリングエンジンをサポートしています
  • Windows、Linux、macOS上で、ローカルまたはCI上で、Google ChromeおよびSafariのエミュレータを使用して非表示(ヘッドレス)または表示しながらテストできます。

入門方法

  • 公式文書で以下くらいをまず読みます。本記事ではそこに書いてあることは基本説明しません。
    • Getting Started
    • Getting started – VS Code
  • 任意のプロジェクトで以下を実施します。
$ pnpm create playwright
  • サンプルのテストコードで、色々試します。最初、以下等のコマンドを実行してみます。
    • 公式文書では、コマンドをnpm 又は npx で実行しています。npxで説明しているところpnpxで試したら動かないことがありました。公式文書どおりにやるほうが無難かもしれません。
$ pnpm exec playwright test
    エンドツーエンドのテストを実行します。

$ pnpm exec playwright test --ui
    インタラクティブな UI モードを起動します。

$ pnpm exec playwright test --project=chromium
    Desktop Chrome でのみテストを実行します。

$ pnpm exec playwright test example
    特定のファイルでテストを実行します。

$ pnpm exec playwright test --debug
    デバッグモードでテストを実行します。

$ pnpm exec playwright codegen
    Codegen を使ってテストを自動生成します。
  • サンプルのテストについて、コマンドではなくVSCodeの拡張機能を入れると追加されるテストエクスプローラを用いて各種実行します。
  • その後、独自のテストを試します。
VSCodeからのPlaywrightの実行

実際に使いはじめて気づいた点など

  • 適切なロケータが出るための工夫が必要なことがある。
    • ロケータとは、ウェブページ上の特定の要素を特定・選択するための識別子や構造。例:id, class, クラスセレクタ、タグ。
    • ロケータはツールがよさげなやつを提案してくれるが、提案されたやつが画面のどこかわからないことがある。
    • 同じコンポーネントを複数使っている場合など、どちらのコンポーネントなのかをテストコードを見ても、判別できなかったりする。
    • 対応策として、例えば次のようにする。ここでのdata-testidはテストにしか使われない(影響しない)。
<n-select v-model:value="themeColor" :options="themeColorOptions" />
    ↓
<n-select v-model:value="themeColor" :options="themeColorOptions" data-testid="theme-color-selector" />
  • アクションを記録すると冗長になりがち。適宜関数化する。
    • VSCodeのテストエクスプローラの[Record new]や[Record at cursor]ボタンをクリックしたあとのブラウザ操作がコードに落ちるが、冗長になることがある。
    • 例:次のようにドロップダウンの切り替えについて1行で記述できるように関数化する。
// ドロップダウンの切り替え
async function selectDropdownOption(page, selectorTestId, buttonText) {
  await page.getByTestId(selectorTestId).locator('svg').click();
  await page
    .locator('div')
    .filter({ hasText: new RegExp(`^${buttonText}$`) })
    .first()
    .click();
    }


// 条件1
await selectDropdownOption(page, 'theme-color-selector', 'ライトモード');
await selectDropdownOption(page, 'editor-color-selector', 'テーマカラーと連動する');
// なにかテスト

// 条件2
await selectDropdownOption(page, 'theme-color-selector', 'ダークモード');
await selectDropdownOption(page, 'editor-color-selector', 'テーマカラーと連動する');
// なにかテスト
  • 要素の色を確認するテストは難しいことがある。
    • 次のような関数を用いて背景色を確認できる場合があるがが、うまくいかないこともある。
// 背景色の確認
async function expectBackgroundColor(page, selector, expectedColor) {
  const bgColor = await page.$eval(selector, (el) => {
    return getComputedStyle(el).backgroundColor;
  });
  expect(bgColor).toBe(expectedColor);
}
  • 例えば次のような場合である。
    • 色をCSS変数を用いている場合は上記方式が使用できない。
    • CSS変数の値が16進数で、得られる値がRGBの場合は変換が必要。
    • CSSがRGBでなくRGBA(透明度を指定)の場合は、実際の色は背景の色との掛け合わせになるので評価が難しい。
      • 複雑な計算で実際の色を出す。
      • RGBAの透明度の部分を無視して比較する。

これ以外にも何かと壁にぶつかり、ノウハウが必要がことがわかりました。別記事に書く予定です。