メインコンテンツにスキップ

ビジュアルテスト

どんなことができるの?

WebdriverIOは、以下のためのスクリーン、要素、またはフルページの画像比較を提供します

  • 🖥️ デスクトップブラウザ(Chrome / Firefox / Safari / Microsoft Edge)
  • 📱 モバイル/タブレットブラウザ(Android エミュレータ上のChrome / iOS シミュレータ上のSafari / シミュレータ / 実機)via Appium
  • 📱 ネイティブアプリ(Android エミュレータ / iOS シミュレータ / 実機)via Appium(🌟 新機能 🌟)
  • 📳 ハイブリッドアプリ via Appium

これらは軽量なWebdriverIOサービスである@wdio/visual-serviceを通じて提供されます。

これにより以下のことが可能になります:

  • スクリーン/要素/フルページのスクリーンショットをベースラインと比較して保存
  • ベースラインがない場合に自動的にベースラインを作成
  • カスタム領域をブロックアウトし、比較中にステータスバーやツールバー(モバイルのみ)を自動的に除外
  • 要素のスクリーンショットのサイズを拡大
  • ウェブサイト比較中にテキストを非表示にして:
    • 安定性を向上させ、フォントのレンダリングのちらつきを防止
    • ウェブサイトのレイアウトにのみ焦点を当てる
  • 異なる比較メソッドと、より読みやすいテストのための追加のマッチャーセットを使用
  • あなたのウェブサイトがキーボードのタブ操作をどのようにサポートするかを検証(ウェブサイトでのタブ操作も参照)
  • その他多くの機能(サービスメソッドのオプションを参照)

このサービスは、すべてのブラウザ/デバイスに必要なデータとスクリーンショットを取得するための軽量モジュールです。比較機能はResembleJSから提供されています。オンラインで画像を比較したい場合は、オンラインツールを確認してください。

ネイティブ/ハイブリッドアプリに関する注意

saveScreensaveElementcheckScreencheckElementのメソッドと、toMatchScreenSnapshotおよびtoMatchElementSnapshotのマッチャーはネイティブアプリ/コンテキストで使用できます。

ハイブリッドアプリで使用する場合は、サービス設定でisHybridApp:trueプロパティを使用してください。

インストール

@wdio/visual-servicepackage.jsonにdev-dependencyとして保持するのが最も簡単な方法です:

npm install --save-dev @wdio/visual-service

使用方法

@wdio/visual-serviceは通常のサービスとして使用できます。設定ファイルで以下のように設定できます:

import path from "node:path";

// wdio.conf.ts
export const config = {
// ...
// =====
// Setup
// =====
services: [
[
"visual",
{
// いくつかのオプション、詳細はドキュメントを参照
baselineFolder: path.join(process.cwd(), "tests", "baseline"),
formatImageName: "{tag}-{logName}-{width}x{height}",
screenshotPath: path.join(process.cwd(), "tmp"),
savePerInstance: true,
// ... その他のオプション
},
],
],
// ...
};

その他のサービスオプションはこちらで確認できます。

WebdriverIO設定でセットアップしたら、テストにビジュアルアサーションを追加できます。

ケイパビリティ

ビジュアルテストモジュールを使用するには、ケイパビリティに追加のオプションを追加する必要はありません。ただし、場合によっては、logNameなどの追加メタデータをビジュアルテストに追加したいことがあります。

logNameを使用すると、各ケイパビリティにカスタム名を割り当てることができ、画像ファイル名に含めることができます。これは、異なるブラウザ、デバイス、または構成間で撮影したスクリーンショットを区別するのに特に役立ちます。

これを有効にするには、capabilitiesセクションでlogNameを定義し、ビジュアルテストサービスのformatImageNameオプションでそれを参照するようにします。設定方法は次のとおりです:

import path from "node:path";

// wdio.conf.ts
export const config = {
// ...
// =====
// Setup
// =====
capabilities: [
{
browserName: 'chrome',
'wdio-ics:options': {
logName: 'chrome-mac-15', // Chromeのカスタムログ名
},
}
{
browserName: 'firefox',
'wdio-ics:options': {
logName: 'firefox-mac-15', // Firefoxのカスタムログ名
},
}
],
services: [
[
"visual",
{
// いくつかのオプション、詳細はドキュメントを参照
baselineFolder: path.join(process.cwd(), "tests", "baseline"),
screenshotPath: path.join(process.cwd(), "tmp"),
// 以下のフォーマットはケイパビリティからの`logName`を使用します
formatImageName: "{tag}-{logName}-{width}x{height}",
// ... その他のオプション
},
],
],
// ...
};

仕組み

  1. logNameの設定:

    • capabilitiesセクションで、各ブラウザまたはデバイスに一意のlogNameを割り当てます。例えば、chrome-mac-15はmacOS バージョン15上のChromeで実行されるテストを識別します。
  2. カスタム画像の命名:

    • formatImageNameオプションはlogNameをスクリーンショットのファイル名に統合します。例えば、tagがhomepageで解像度が1920x1080の場合、結果のファイル名は次のようになります:

      homepage-chrome-mac-15-1920x1080.png

  3. カスタム命名の利点:

    • 異なるブラウザやデバイスからのスクリーンショットを区別することがはるかに簡単になり、特にベースラインの管理や不一致のデバッグに役立ちます。
  4. デフォルトに関する注意:

    • logNameがケイパビリティで設定されていない場合、formatImageNameオプションはファイル名に空の文字列として表示します(homepage--15-1920x1080.png

WebdriverIO MultiRemote

MultiRemoteもサポートしています。これを適切に機能させるには、以下のようにwdio-ics:optionsをケイパビリティに追加してください。これにより、各スクリーンショットが独自の一意の名前を持つようになります。

テストの記述testrunnerの使用と比較して異なることはありません。

// wdio.conf.js
export const config = {
capabilities: {
chromeBrowserOne: {
capabilities: {
browserName: "chrome",
"goog:chromeOptions": {
args: ["disable-infobars"],
},
// これを追加!
"wdio-ics:options": {
logName: "chrome-latest-one",
},
},
},
chromeBrowserTwo: {
capabilities: {
browserName: "chrome",
"goog:chromeOptions": {
args: ["disable-infobars"],
},
// これを追加!
"wdio-ics:options": {
logName: "chrome-latest-two",
},
},
},
},
};

プログラムで実行

以下はremoteオプションを介して@wdio/visual-serviceを使用する最小限の例です:

import { remote } from "webdriverio";
import VisualService from "@wdio/visual-service";

let visualService = new VisualService({
autoSaveBaseline: true,
});

const browser = await remote({
logLevel: "silent",
capabilities: {
browserName: "chrome",
},
});

// カスタムコマンドを`browser`に追加するためにサービスを「開始」する
visualService.remoteSetup(browser);

await browser.url("https://webdriver.io/");

// スクリーンショットを保存するためだけに使用する場合
await browser.saveFullPageScreen("examplePaged", {});

// または検証に使用する場合。両方のメソッドを組み合わせる必要はありません、FAQを参照
await browser.checkFullPageScreen("examplePaged", {});

await browser.deleteSession();

ウェブサイトでのタブ操作

キーボードのTABキーを使用してウェブサイトがアクセス可能かどうかを確認できます。アクセシビリティのこの部分をテストすることは常に時間のかかる(手動の)作業であり、自動化を通じて行うのは非常に難しいものでした。 saveTabbablePageおよびcheckTabbablePageメソッドを使用すると、ウェブサイト上に線と点を描画してタブ移動順序を確認できるようになりました。

これはデスクトップブラウザにのみ有用であり、モバイルデバイスには使用できない点に注意してください。すべてのデスクトップブラウザはこの機能をサポートしています。

メモ

この機能はViv Richardsのブログ記事"AUTOMATING PAGE TABABILITY (IS THAT A WORD?) WITH VISUAL TESTING"からインスピレーションを得ています。

タブ可能な要素の選択方法はtabbableモジュールに基づいています。タブ操作に関する問題がある場合は、README.md、特に詳細セクションを確認してください。

仕組み

両方のメソッドはウェブサイト上にcanvas要素を作成し、エンドユーザーがTABを使用した場合の移動先を示す線と点を描画します。その後、全体の流れを把握するためにフルページスクリーンショットを作成します。

important

スクリーンショットを作成するだけで、ベースライン画像と比較したくない場合にのみsaveTabbablePageを使用してください。

タブ移動の流れをベースラインと比較したい場合は、checkTabbablePageメソッドを使用できます。2つのメソッドを一緒に使用する必要はありません。サービスをインスタンス化するときにautoSaveBaseline: trueを提供することで自動的に作成できるベースライン画像がすでに存在する場合、 checkTabbablePageはまず_実際の_画像を作成し、それをベースラインと比較します。

オプション

両方のメソッドはsaveFullPageScreenまたは compareFullPageScreenと同じオプションを使用します。

これはテスト用ウェブサイトでのタブ操作の例です:

WDIO tabbing example

失敗したビジュアルスナップショットを自動的に更新する

コマンドラインに引数--update-visual-baselineを追加してベースライン画像を更新します。これにより

  • 実際に取得したスクリーンショットを自動的にコピーしてベースラインフォルダに配置
  • 差分がある場合でも、ベースラインが更新されたためテストは合格となります

使用方法:

npm run test.local.desktop  --update-visual-baseline

ログのinfo/debugモードで実行すると、以下のようなログが追加されます

[0-0] ..............
[0-0] #####################################################################################
[0-0] INFO:
[0-0] Updated the actual image to
[0-0] /Users/wswebcreation/Git/wdio/visual-testing/localBaseline/chromel/demo-chrome-1366x768.png
[0-0] #####################################################################################
[0-0] ..........

Typescriptサポート

このモジュールはTypeScriptをサポートしており、ビジュアルテストサービスを使用する際に自動補完、型安全性、および改善された開発者エクスペリエンスの恩恵を受けることができます。

ステップ1:型定義の追加

TypeScriptがモジュールの型を認識するようにするには、tsconfig.jsonのtypesフィールドに次のエントリを追加します:

{
"compilerOptions": {
"types": ["@wdio/visual-service"]
}
}

ステップ2:サービスオプションの型安全性を有効にする

サービスオプションの型チェックを強制するには、WebdriverIO設定を更新します:

// wdio.conf.ts
import { join } from 'node:path';
// 型定義をインポート
import type { VisualServiceOptions } from '@wdio/visual-service';

export const config = {
// ...
// =====
// Setup
// =====
services: [
[
"visual",
{
// サービスオプション
baselineFolder: join(process.cwd(), './__snapshots__/'),
formatImageName: '{tag}-{logName}-{width}x{height}',
screenshotPath: join(process.cwd(), '.tmp/'),
} satisfies VisualServiceOptions, // 型安全性を確保
],
],
// ...
};

システム要件

バージョン5以降

バージョン5以降、このモジュールは一般的なプロジェクト要件以外に追加のシステム依存関係がない純粋なJavaScriptベースのモジュールです。画像処理ライブラリとしてJimpを使用しており、これは完全にJavaScriptで書かれたNodeのライブラリで、ネイティブな依存関係はありません。

バージョン4以下

バージョン4以下では、このモジュールはNode.js用のキャンバス実装であるCanvasに依存しています。CanvasはCairoに依存しています。

インストールの詳細

デフォルトでは、macOS、Linux、およびWindows用のバイナリがプロジェクトのnpm install中にダウンロードされます。サポートされているOSやプロセッサアーキテクチャがない場合、モジュールはシステム上でコンパイルされます。これにはCairoやPangoを含むいくつかの依存関係が必要です。

詳細なインストール情報については、node-canvasのwikiを参照してください。以下は一般的なオペレーティングシステム用のワンラインインストール手順です。libgif/gifliblibrsvglibjpegはオプションであり、それぞれGIF、SVG、JPEGサポートにのみ必要です。Cairo v1.10.0以降が必要です。

Homebrewを使用:

brew install pkg-config cairo pango libpng jpeg giflib librsvg pixman

Mac OS X v10.11+: 最近Mac OS X v10.11+に更新して問題が発生している場合は、次のコマンドを実行してください:xcode-select --install。この問題の詳細についてはStack Overflowを参照してください。 Xcode 10.0以上がインストールされている場合、ソースからビルドするにはNPM 6.4.1以上が必要です。

Welcome! How can I help?

WebdriverIO AI Copilot