WebExtensions の E2E テスト自動化ツール『lanthan』を作りました。 元々は Vim Vixen の E2E テストを自動化するために開発を始めたのですが、独立したモジュールとして切り出したため、様々な WebExtensions の E2E テストに利用できます。
以前、WebExtensions の E2E テスト自動化の取り組みについて記事を書きました。
この仕組みは、テスト実行を Karma などを使ってブラウザ上で実行する必要があり、制限が多くメンテナンス性も乏しかったです。 この記事で紹介する lanthan は別のアプローチで WebExtensions の E2E テストを実行できます。 lanthan は設計を見直して 1 から作り直したライブラリで、現在の Vim Vixen も lanthan を使って E2E テストを自動実行しています。
インストール
lanthan はnpmパッケージとして公開しています。
npm install
でインストールできます。
$ npm install -D lanthan
package.json
のdevDependencies
に直接記述することでインストールできます。
{
"devDependencies": {
"lanthan": "0.0.2"
}
}
クイックスタート
いくつかのサンプルをプロジェクトのexamples
ディレクトリに用意してあります。
lanthan のセットアップと終了処理 (examples/01_setup_teardown.js
)
lanthan
パッケージは、ビルダークラス Builder
を提供しています。
// Common JS
const { Builder } = require("lanthan")
// ES Module
import { Builder } from "lanthan"
Builder
はブラウザのセッションを作成して、ブラウザにアクセスする API を提供します。
Builder
は static メソッドforBrowser()
で初期化します。
現在は"firefox"
のみサポートしてます。
build()
を呼び出すことで、Firefox が起動して、ブラウザにアクセスできる Lanthan
オブジェクトを返します。
let lanthan = await Builder.forBrowser("firefox").build()
ブラウザのセッションを閉じるには quit()
メソッドを呼び出します。
await lanthan.quit()
WebExtensions API を取得する (examples/02_webext_api.js
)
lanthan のブラウザセッションは、リモート WebExtensions API を提供します。 これは WebExtensions 互換の API ですが、ブラウザの外から呼び出せます。 つまり Node.js などのローカル環境からブラウザを制御したり、WebExtensions の振る舞いを検証できます。
Lanthan
オブジェクトの getWebExtBrowser()
メソッドは WebExtensions API 互換のオブジェクトを返します。
// WebExtensions APIを取得
let browser = lanthan.getWebExtBrowser()
たとえば、タブを作成したり、現在のタブを取得できます。
// タブを作成する
await browser.tabs.create({ url: "https://example.com/" })
await browser.tabs.create({ url: "https://example.org/" })
// 全てのタブを取得する
let tabs = await browser.tabs.query({})
// 取得したタブを検証する
assert.strictEqual(tabs.length, 3)
WebDriver API を取得する (examples/03_webdriver_api.js
)
lanthan は Selenium WebDriver API も提供しています。 キーイベントを送信したり、DOM を検証したり、JavaScript を実行できます。 この API はテスト自動化に役立ちます。
Lanthan
オブジェクトの getWebDriver()
メソッドは、Selenium WebDriver API を返します。
// WebDriver APIを取得
let webdriver = lanthan.getWebDriver()
たとえば、ページを開いてリンクをクリックする例は以下のとおりです。
// Open https://example.com/
await webdriver.navigate().to("https://example.com/")
await webdriver.findElement(By.css("a")).click()
Selenium WebDriver API の詳しい情報は、Selenium projectやJavaScipt API ドキュメントを参照してください。
Add-on への spy (examples/04_spy_addon.js
)
Lanthan はリモートから WebExtensions API を呼び出すために、HTTP サーバーを立てる add-on をインストールします。 これは 1 つの独立したアドオンですが、既存のアドオンに組み込むこともできます(spy)。 既存のアドオンに spy することで、内部状態(たとえば local storage)などにアクセスできます。
lanthan プロジェクトのexamples/addon
に、サンプル add-on を用意しました。
このアドオンはページ内の打鍵数をカウントして、local storage にページ origin ごとの打鍵回数を保存します。
lanthan が add-on を spy するには、ビルダーオブジェクトのspyAddon()
メソッドを呼び出します。
let lanthan = await Builder.forBrowser("firefox") // Lanthan currently supports only Firefox
.spyAddon(path.join(__dirname, "addon")) // Spy to the add-on
.build()
リモート WebExtensions API はターゲットアドオンの local storage にアクセスできるので、テストなどで検証できます。
let { count } = await browser.storage.local.get("count")
assert.strictEqual(count["https://example.com"], 1)
assert.strictEqual(count["https://example.org"], 3)
assert.strictEqual(count["https://example.net"], undefined)
まとめ
lanthan は Vim Vixen の E2E 自動化のために始めたプロジェクトですが、npm パッケージとして切り出して Vim Vixen 以外にも利用できるようにしました。 Vim Vixen は 100 を超えるテストケースを、lanthan を使って CircleCI 上で E2E テストを実行しています。
lanthan の開発は GitHub 上で進めています。 今後の開発の動向はそちらを参照してください。