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 lanthanpackage.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 上で進めています。 今後の開発の動向はそちらを参照してください。