ビジュアルテスト
どんなことができるの?
WebdriverIOは、以下のためのスクリーン、要素、またはフルページの画像比較を提供します
- 🖥️ デスクトップブラウザ(Chrome / Firefox / Safari / Microsoft Edge)
- 📱 モバイル/タブレットブラウザ(Android エミュレータ上のChrome / iOS シミュレータ上のSafari / シミュレータ / 実機)via Appium
- 📱 ネイティブアプリ(Android エミュレータ / iOS シミュレータ / 実機)via Appium(🌟 新機能 🌟)
- 📳 ハイブリッドアプリ via Appium
これらは軽量なWebdriverIOサービスである@wdio/visual-service
を通じて提供されます。
これにより以下のことが可能になります:
- スクリーン/要素/フルページのスクリーンショットをベースラインと比較して保存
- ベースラインがない場合に自動的にベースラインを作成
- カスタム領域をブロックアウトし、比較中にステータスバーやツールバー(モバイルのみ)を自動的に除外
- 要素のスクリーンショットのサイズを拡大
- ウェブサイト比較中にテキストを非表示にして:
- 安定性を向上させ、フォントのレンダリングのちらつきを防止
- ウェブサイトのレイアウトにのみ焦点を当てる
- 異なる比較メソッドと、より読みやすいテストのための追加のマッチャーセットを使用
- あなたのウェブサイトがキーボードのタブ操作をどのようにサポートするかを検証(ウェブサイトでのタブ操作も参照)
- その他多くの機能(サービスとメソッドのオプションを参照)
このサービスは、すべてのブラウザ/デバイスに必要なデータとスクリーンショットを取得するための軽量モジュールです。比較機能はResembleJSから提供されています。オンラインで画像を比較したい場合は、オンラインツールを確認してください。
saveScreen
、saveElement
、checkScreen
、checkElement
のメソッドと、toMatchScreenSnapshot
およびtoMatchElementSnapshot
のマッチャーはネイティブアプリ/コンテキストで使用できます。
ハイブリッドアプリで使用する場合は、サービス設定でisHybridApp:true
プロパティを使用してください。
インストール
@wdio/visual-service
をpackage.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}",
// ... その他のオプション
},
],
],
// ...
};
仕組み
-
logName
の設定:capabilities
セクションで、各ブラウザまたはデバイスに一意のlogName
を割り当てます。例えば、chrome-mac-15
はmacOS バージョン15上のChromeで実行されるテストを識別します。
-
カスタム画像の命名:
-
formatImageName
オプションはlogName
をスクリーンショットのファイル名に統合します。例えば、tag
がhomepageで解像度が1920x1080
の場合、結果のファイル名は次のようになります:homepage-chrome-mac-15-1920x1080.png
-
-
カスタム命名の利点:
- 異なるブラウザやデバイスからのスクリーンショットを区別することがはるかに簡単になり、特にベースラインの管理や不一致のデバッグに役立ちます。
-
デフォルトに関する注意:
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を使用した場合の移動先を示す線と点を描画します。その後、全体の流れを把握するためにフルページスクリーンショットを作成します。
スクリーンショットを作成するだけで、ベースライン画像と比較したくない場合にのみsaveTabbablePage
を使用してください。
タブ移動の流れをベースラインと比較したい場合は、checkTabbablePage
メソッドを使用できます。2つのメソッドを一緒に使用する必要はありません。サービスをインスタンス化するときにautoSaveBaseline: true
を提供することで自動的に作成できるベースライン画像がすでに存在する場合、
checkTabbablePage
はまず_実際の_画像を作成し、それをベースラインと比較します。
オプション
両方のメソッドはsaveFullPageScreen
または
compareFullPageScreen
と同じオプションを使用します。
例
これはテスト用ウェブサイトでのタブ操作の例です:
失敗したビジュアルスナップショットを自動的に更新する
コマンドラインに引数--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/giflib
、librsvg
、libjpeg
はオプションであり、それぞれGIF、SVG、JPEGサポートにのみ必要です。Cairo v1.10.0以降が必要です。
- OS
- Ubuntu
- Fedora
- Solaris
- OpenBSD
- Window
- Others
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以上が必要です。
sudo apt-get install build-essential libcairo2-dev libpango1.0-dev libjpeg-dev libgif-dev librsvg2-dev
sudo yum install gcc-c++ cairo-devel pango-devel libjpeg-turbo-devel giflib-devel
pkgin install cairo pango pkg-config xproto renderproto kbproto xextproto
doas pkg_add cairo pango png jpeg giflib
wikiを参照してください
wikiを参照してください