Quantcast
Channel: @jsakamoto
Viewing all articles
Browse latest Browse all 144

Selenium WebDriver C# バインディングのリモートセッションを通して ".xpi"ブラウザ拡張機能をインストールし、テストする方法

$
0
0
Selenium で Mozilla ブラウザ拡張の E2E テストを書く
Web ブラウザをリモート操作する WebDriver の一つである "GeckoDriver" (通称 "FirefoxDriver") は、リモート操作のセッションで ".xpi" Mozillaブラウザ拡張ファイルをインストールする機能を提供している。


この機能は、手元で開発中の Mozilla ブラウザ拡張に対し、End-to-End テストを実施するのに便利である。


しかし残念ながら、自分が実際に ".xpi" ブラウザ拡張をインストールする Selenium GeckoDriver を使った End-to-End テストを実装したところ、ちゃんと動作するようになるまでに、いくつかの落とし穴に遭遇する羽目になってしまった。そこで今回は、Selenium GeckoDriver を使って ".xpi" ファイルをインストールするベストな方法を共有したいと思う。


なお、自分は C# (.NET) で Seleium を常用しているため、以下では Selenium の C# バインディングに基づいて説明する。


"FirefoxProfile.AddExtension" を使ってはいけない
Visual Studio などの IDE 上で開発していると、そのインテリセンスなどで、 "FirefoxProfile" クラスに "AddExtension()" というメソッドがあることに気づくかも知れない。見た感じ、このメソッド名は、拡張機能をインストールするのに最適な機能であるように感じる。


しかしそのメソッド名の見た目に反して、 "FirefoxProfile.AddExtension()" メソッドは正しく動作しなかった。なぜこのメソッドが自分が期待したようには動作しないのか (仕様なのか使用方法が間違っているのか) はとくに深追いしていないためわかっていないが、とにかく、このメソッドで拡張機能をインストールできたことは一度もない。


// ⚠️ これは NG! 😱
var profile = new FirefoxProfile();
profile.AddExtension(pathToXpiFile);





"FirefoxDriver.InstallAddOnFromFile" を使用する
代わりに、"FirefoxDriver" の "InstallAddOnFromFile() "メソッドを使うとよい。このメソッドの第一引数には、".xpi "ファイルへのフルパスを指定する。FirefoxDriver.InstallAddOnFromFile" メソッドは期待どおり正常に動作し、ブラウザ拡張がインストールされた。特に難しいことは何もなかった。


// 👍 これなら OK! 😊
using var driver = new FirefoxDriver();
driver.InstallAddOnFromFile(pathToXpiFile);




なお、"FirefoxDriver" クラスは "InstallAddOn()" メソッドも公開しており、こちらはブラウザ拡張機能のバイナリコンテンツを base64 エンコードされた文字列として指定することができる。


"FirefoxProfile.SetPreference" を使ってはいけない
ブラウザ拡張機能の End-to-End テストにおいては、ストアの審査に提出する前の開発段階であるからして、 ".xpi" ブラウザ拡張ファイルには署名が施されていないのが通常だ。しかし、Web ブラウザは通常、セキュリティ上の問題から、署名されていないブラウザ拡張ファイルのインストールを拒否するのが既定の設定である。そこで、End-to-End テスト時には、 Web ブラウザのこの制限・制約を一時無効にする必要がでてくる。


ということで、署名なし拡張のインストール方法をインターネット検索してみると、その検索結果に、環境設定 "xpinstall.signatures.required" を false に設定する方法を見つけることができる。


しかし、"FirefoxProfile" クラスの "SetPreference" メソッドを使用する以下のコードは、決してうまくいかなかった。具体的には、下記コードを実行すると、


// ⚠️ これは NG! 😱
var profile = new FirefoxProfile();
profile.AddExtension(pathToXpiFile);





以下のような例外が発生してしまうのだ。


System.ArgumentException: Preference xpinstall.signatures.required may not be overridden:
frozen value=False, requested value=False"

"FirefoxOptions.SetPreference" を使用する
ではどうするかというと、 "FirefoxProfile" クラスではなく、 "FirefoxOptions" クラスの "SetPreference "メソッドを使用する。この方法なら問題なく動作する。


// 👍 これは OK! 😊
var option = new FirefoxOptions();
option.SetPreference("xpinstall.signatures.required", false);
using var driver = new FirefoxDriver(option);




通常版 Firefox を使ってはいけない
ここまで済ませてもなお、以下の実行時エラーに遭遇してしまった。
Could not install add-on: ....xpi: ERROR_SIGNEDSTATE_REQUIRED:
The addon must be signed and isn't.

インターネット検索でいろいろ調べた結果、どうやら環境設定を如何にしようとも、通常版の Firefox ブラウザでは、署名されていない ".xpi" ブラウザ拡張ファイルのインストールは、絶対に許可されないように実装されているようである。


Firefox の Developer または Enterprise エディションを使用する
この問題ついては PC に Firefox Web ブラウザーの Developer Edition または Enterprise Edition をインストールし、通常版ではなくそれら Edition 上で実行することで解決される。Firefox Developer Edition の詳細については、以下のリンクを参照。


まとめ
Selenium WebDriver を使って ".xpi" ブラウザ拡張ファイルをインストールするために、なぜこんなに落とし穴があるのかよくわかってはいない。何か歴史的事情なのか、あるいは自分が使い方をよくわかっていないだけなのか。何はともあれ、この記事が他の開発者の時間を節約する助けになれば幸いである。


この記事のサンプルコード全体は、以下の GitHub リポジトリで見ることができる。






Viewing all articles
Browse latest Browse all 144

Trending Articles