こんにちは! みなさんmacOSしてますか!
アップグレード中にフリーズしたせいでリカバリーするのがたいへんだったよ!!! クソが!!!!
なんでわざわざそんなクソなアップグレードを急いでやったかというと、Safariの新バージョンが動く最新の環境で確認したいことがあったからです。AppleによるネイティブサポートのWebDriverです!
Safari 10から、WebDriverがネイティブサポートされることになりました。
これまで、 MacOS Xの標準WebブラウザーであるSafariをWebDriverで自動操作するためには、専用の拡張機能プラグインが利用されていました。
新しくリリースされたSafari 10からは、このプラグインを使わなくても、OS側でWebDriverをサポートしてくれることになりました!
Appleの開発者向けWebサイトには SafariDriverの対応コマンド表 こそ掲載されていますが、現状で最もよくまとまっている公式っぽい導入ドキュメントは WebKitの公式ブログ記事 くらいではないでしょうか。この記事に載っている情報も含め、新しいSafariDriverを具体的にどのように利用できるか確認してみましょう。
新しいSafariDriverやってみよう
新しいSafariをSeleniumで操作するときは、他のブラウザーと同様にSafariDriverサーバーを仲介役として併用することになりました。
Safari 10が導入された環境では、 /usr/bin/safaridriver
にSafariDriverサーバーの実行ファイルが置かれています。
$ ls -l /usr/bin/safaridriver
-rwxr-xr-x 1 root wheel 34384 9 14 09:56 /usr/bin/safaridriver
普通は /usr/bin
にはPATHが通っていると思いますので、特に環境変数をいじらなくてもすぐに使えるはずですね。
初回起動時だけ、セキュリティーに関する確認ダイアログが表示されます。
ここで実行を許可しておけば、次回からはダイアログは表示されません。
待ち受けポート番号を指定する --port
オプションに、既定値を利用する意味の 0
を指定して初回起動を済ませてみましょう。(なお、既定の待ち受けポートは7055/tcpです)
$ /usr/bin/safaridriver --port 0
Could not find the required security authorization right, `safaridriver` will attempt to create it.
Please allow `safaridriver` to make the required changes to the security authorization database.
さて、これだけではSafariをWebDriverから操作できません。
リモート操作できるAPIがあるということは、セキュリティー上のリスクがあるということです。Safariではセキュリティー上の理由で、WebDriverで動かすことを明示的に許可する設定が必要になります。
環境設定の詳細タブで、チェックボックス「メニューバーに"開発"メニューを表示」にチェックを入れましょう。
Safariのメニューに「開発」が表示されるようになります。
「リモートオートメーションを許可」を選択して、チェックが入っている状態にしましょう。
これで、SafariをWebDriverから動かす準備ができました。
先ほど起動したSafariDriverサーバーが開いている7055/tcpにWebDriver APIへのリクエストを投げれば、Safariを自動操作することができます。
自動操作されているSafariは、アドレスバーが黄色になってわかりやすくなっています。
また、自動操作されているSafariにフォーカスを合わせると、自動操作されていることを示すダイアログが表示され、不用意にユーザー操作されないようになっています。
公式クライアントライブラリーはバージョン3から対応です。
Selenium の公式クライアントライブラリーでの対応は、最新バージョンの3からです。2系では使えませんしたぶんバックポートもされないので、無駄な抵抗はやめて3系に移行しJava 7も早急に捨てるのだのだのだ(残響音含む)
正確には、Selenium 3.0.0 beta4から新しいSafariDriverに対応しています。ぜひ試してみましょう!
なお、beta3まではバージョン3系で以前のオープンソース版のプラグインを利用するための useLegacyDriver
というcapabilitiesが残っていたのですが、beta4では削除されてしまいました。今後、以前のプラグインはもう使えないと考えた方が良いでしょう。
スクリーンショットが一癖あります。
- SafariDriverサーバーの スクリーンショットを取得するWebDriver API で返ってくるBASE64データが、ChromeDriverサーバーやGeckoDriverサーバーなどと違って、スラッシュ記号がエスケープされた状態になっています。これはJSON仕様としては正しい(エスケープしてもしなくてもいい)実装で、公式クライアントライブラリーもこれに対応して正しくスクリーンショットのデータを取得できる状態になっています。 直接WebDriver APIを叩いていたbash野郎 は気をつけましょう!!!
ベンチマーク
日本Seleniumユーザーコミュニティの提供するサンプルページ上で基本的なAPIを100回実行して、1回あたりの平均値を取得するだけの簡易ベンチマークをやりました。
https://github.com/hiroshitoda/WebDriverBenchmark
実行環境は手元のMacBook Pro実機で、スペックは次の通りです。
CPU | Intel Core i5 2.5GHz |
メモリー | 16Gbytes |
OS | macOS Sierra 10.12 |
JDK | 1.8.0_101-b13 |
結果は次の通りでした。なかなか軽快に動くのがわかりますね。
ChromeDriver | FirefoxDriver via GeckoDriver | PhantomJSDriver | SafariDriver | |
---|---|---|---|---|
WebDriver.get | 289ms | 249ms | 49ms | 48ms |
WebDriver.findElement(By.Id) | 13ms | 10ms | 10ms | 7ms |
WebDriver.findElement(By.cssSelector) | 11ms | 9ms | 8ms | 5ms |
WebElement.clear | 64ms | 21ms | 21ms | 9ms |
WebElement.sendKeys | 70ms | 23ms | 32ms | 66ms |
WebElement.click | 55ms | 23ms | 39ms | 10ms |
TakeScreenshot.getScreenshotAs | 119ms | 45ms | 50ms | 24ms |