Laravel5.4のブラウザテスト（Laravel Dusk）で使えるメソッドを調べる

# はじめに
Laravel5.4ではアプリケーションテストとして、実際にブラウザを動かすLaravel Dusk(ダースク)を使います。
Laravel DuskはChromeを動かすためのテストツールです。

https://laravel.com/docs/5.4/dusk

このLaravel Duskは5.4から登場しました。
Laravelは次の5.5がLTSになる予定ですので、今後のアプリケーションテストはLaravel Duskを使っておくと良さそうです。

Laravel Duskについてはまだ情報が少なく、どうやってテストしたらよいかわかりませんでした。
そこでどういった機能があるのか、リファレンス的なものを知りたかったので調べてみました。

# 基本的な記述とソースコードについて

公式サイトではDuskのチュートリアル的なサンプルコードが載っています。

その一部のうち、Duskで動かす部分を見てみます。

```php
$this->browse(function ($browser) use ($user) {
	$browser->visit('/login')
	        ->type('email', $user->email)
	        ->type('password', 'secret')
	        ->press('Login')
	        ->assertPathIs('/home');
});
```

上記コードのうち、`$browser`がDuskのBrowserクラスのインスタンスです。
このインスタンスに対して定義されているメソッドを利用することができます。

# PhpStormでの補完
どんなメソッドがあるのか補完を効かせるため、型指定を明示しました。

```php
$this->browse(function ($browser) use ($user) {
/** @var \Laravel\Dusk\Browser $browser */
$browser->visit('/login')
```

こんな感じで補完することができます。

![Screen Shot 2017-08-24 at 16.42.08.png](https://qiita-image-store.s3.amazonaws.com/0/47327/5b373c52-56ff-e750-4514-776a3da3c395.png)


補完便利ですね！


# メソッド一覧
とは言え補完だけではコードが書きにくいです。
事前にどういったメソッドがあるのか知っておきたいので調べてみました。
`vendor/laravel/dusk/src/Browser.php` で `use`しているメソッドが有効になっています。

といっても全てチェックする元気がないためコメントを流し読み程度です。

## Browserクラス

BrowserクラスではDuskブラウザの基本的なメソッドなどが定義されています。
URLを開く、閉じる、リロードなどの基本的な動作に加えて、スクリーンショットを取る、ウィンドウサイズを変更するといったこともできます。

メソッド名 | 説明
-----|------
`visit($url)` | URLを開く。
`visitRoute($route, $parameters = [])` | ルートを開く。
`on($page)` | 現在のページオブジェクトを設定する。
`refresh()` | リフレッシュ（リロード）する。
`back()` | ブラウザで「戻る」。
`maximize()` | 最大化する。
`resize($width, $height)` | ウィンドウサイズを変更する。
`screenshot($name)` | スクリーンショットを取る。
`storeConsoleLog($name)` | コンソールログを取る。　
`with($selector, Closure $callback)` | 引数に渡されたクロージャを実行する。
`ensurejQueryIsAvailable()` | jQueryを有効化する。
`pause($milliseconds)` | ウェイトをかけてミリ秒の間待つ。
`quit()` | 終了する。ブラウザを閉じる。
`tap($callback)` | タップする。
`dump()` | 最後の出力を表示する。(dd()を使う。)
`stop()` | ブラウザをそのままにしてテストを終了する。

スクリーンショット機能はありがたいですね。Behatでもスクリーンショット機能がありましたが、非常に助かります。
Duskなどのテストフレームワークはそこそこ高速に直接Chromeを制御するため、どういった順序で進んでいるのか分かりにくいという欠点があります。
確認できるとすごく捗りますね。

## InteractsWithElements クラス

InteractsWithElementsクラスではHTMLの要素についてのメソッドが定義されています。
特にフォーム周りを操作する type(), radio(), select()などはよく使われるメソッドだと思います。
引数の$selectorはCSSセレクタを入れます。
フォーム関連ではname属性を，press()ではButtonタグで囲まれたテキストを受け付けます。

メソッド名 | 説明
-----|-----
`elements($selector)` | 全ての要素を取得する。  
`element($selector)` | 要素をひとつだけ取得する。
`click($selector)` | クリックする。
`rightClick($selector)` | 右クリックする。
`clickLink($link)` | 右クリックする。
`value($selector, $value = null)` | inputタグの値を直接 セット(or ゲット）する。
`text($selector)` | 要素のテキストを取得する。
`attribute($selector, $attribute)` | 要素の値を取得する。
`keys($selector, ...$keys)` | 要素のキーを取得する。
`type($field, $value)` | inputタグに値を入力する。
`clear($field)` | クリアする。
`select($field, $value = null)` | ドロップダウンで値を選択する。
`radio($field, $value)` | ラジオボタンで値を選択する。
`check($field, $value = null)` | チェックボックスでチェック済みにする。
`uncheck($field, $value = null)` | チェックボックスでチェックを外す。
`attach($field, $path)` | 添付ファイルを設定する。
`press($button)` | テキスト、nameで与えられたボタン要素を押下する。
`pressAndWaitFor($button, $seconds = 5)` | テキスト、nameで与えられたボタンを押して秒数を待つ。
`drag($from, $to)` | セレクタで指定された要素をドラッグアンドドロップする。
`dragUp($selector, $offset)` | ドラッグする。
`dragDown($selector, $offset)` | （ドラッグアンド）ドロップする。
`dragLeft($selector, $offset)` | 左にドラッグする。
`dragRight($selector, $offset)` | 右にドラッグする。
`dragOffset($selector, $x = 0, $y = 0)` | 座標分のドラッグする。
`acceptDialog()` | JavaScriptのダイアログで「OK」（許可）を押す。
`dismissDialog()` | JavaScriptのダイアログで「キャンセル」（拒否）を押す。

InteractsWithElementsという名前だけあって、HTML要素やJavaScriptについて細かく動作させることができるようです。
以前BehatというPHP製のテストフレームワークを利用しましたが、フォームやHTML要素についてはほとんど対応できませんでした。
JavaScript動作なども動きません。
Behat名人に聞いたところ「Behatはあくまでサーバサイドロジックのテストに特化しているため、そういったテストはmochaなどで行った方が良いよ」ということでした。なるほど
それに比べるとDuskはなんでもやってしまえ感が強い気がしますね。

# まとめ
今後はLaravel Duskがアプリケーションテストのベースになっていくようですね。
テストは便利だなーと思うんですが、書き方に慣れるまではそこに時間を取られることも多くて悩んでしまいます。
でもロジカルな部分については積極的に書いていってみたいですね。　

アサートについては公式に載ってたのでそちらを参考にします。

https://laravel.com/docs/5.4/dusk#available-assertions

# 参考サイト
https://laravel.com/docs/5.4/dusk
https://readouble.com/laravel/5.4/ja/dusk.html
http://qiita.com/amymd/items/0a5f2705e29972d0d22e
http://qiita.com/n_mogi/items/b96ccc1df31aa5fb859a