イントロダクションIntroduction
Laravel Dusk(ダースク:夕暮れ)は、利用が簡単なブラウザの自動操作/テストAPIを提供します。デフォルトのDuskは皆さんのマシンへ、JDKやSeleniumのインストールを求めません。代わりにDuskはスタンドアローンのChromeDriverを使用します。しかし、好みのSeleniumコンパチドライバも自由に使用することもできます。Laravel Dusk provides an expressive, easy-to-use browser automation and testing API. By default, Dusk does not require you to install JDK or Selenium on your machine. Instead, Dusk uses a standalone ChromeDriver[https://sites.google.com/a/chromium.org/chromedriver/home] installation. However, you are free to utilize any other Selenium compatible driver you wish.
インストールInstallation
使用を開始するには、laravel/dusk
コンポーサ依存パッケージをプロジェクトへ追加します。To get started, you should add the laravel/dusk
Composer dependency to your project:
composer require --dev laravel/dusk
Note: {note} If you are manually registering Dusk's service provider, you should never register it in your production environment, as doing so could lead to arbitrary users being able to authenticate with your application.
本番環境にDuskをインストールしてはいけません。インストールすると、アプリケーションに対する未認証でのアクセスを許すようになります。
Duskパッケージをインストールし終えたら、dusk:install
Artisanコマンドを実行します。After installing the Dusk package, run the dusk:install
Artisan command:
php artisan dusk:install
test
ディレクトリ中に、サンプルテストを含んだBrowser
ディレクトリが作成されます。次に、.env
ファイルでAPP_URL
環境変数を指定します。この値は、ブラウザからアクセスするアプリケーションで使用するURLと一致させます。A Browser
directory will be created within your tests
directory and will contain an example test. Next, set the APP_URL
environment variable in your .env
file. This value should match the URL you use to access your application in a browser.
テストを実行するには、dusk
Artisanコマンドを使います。dusk
コマンドには、phpunit
コマンドが受け付ける引数をすべて指定できます。To run your tests, use the dusk
Artisan command. The dusk
command accepts any argument that is also accepted by the phpunit
command:
php artisan dusk
dusk
コマンドで最後に実行したテストが失敗した場合、dusk:fails
コマンドを使用し、失敗したテストを再実行することにより、時間を節約できます。If you had test failures the last time you ran the dusk
command, you may save time by re-running the failing tests first using the dusk:fails
command:
php artisan dusk:fails
ChromeDriverインストールの管理Managing ChromeDriver Installations
Laravel Duskにデフォルトで含まれるChromeDriverとは別のバージョンをインストールしたい場合は、dusk:chrome-driver
コマンドが使用できます。If you would like to install a different version of ChromeDriver than what is included with Laravel Dusk, you may use the dusk:chrome-driver
command:
# OSに合う、最新バージョンのChromeDriverのインストール
php artisan dusk:chrome-driver
# OSに合う、指定バージョンのChromeDriverのインストール
php artisan dusk:chrome-driver 74
# 全OSをサポートしている、指定バージョンのChromeDriverのインストール
php artisan dusk:chrome-driver --all
Note:
Dusk実行には、実行可能なchromedriver
バイナリが必要です。Dusk実行時に問題がある場合は、このバイナリを実行可能に確実にするために、chmod -R 0755 vendor/laravel/dusk/bin
コマンドを実行してみてください。{note} Dusk requires thechromedriver
binaries to be executable. If you're having problems running Dusk, you should ensure the binaries are executable using the following command:chmod -R 0755 vendor/laravel/dusk/bin/
.
他ブラウザの使用Using Other Browsers
デフォルトのDuskは、Google ChromeとスタンドアローンのChromeDriverをブラウザテスト実行に使用します。しかし、自身のSeleniumサーバを起動し、希望するブラウザに対しテストを実行することもできます。By default, Dusk uses Google Chrome and a standalone ChromeDriver[https://sites.google.com/a/chromium.org/chromedriver/home] installation to run your browser tests. However, you may start your own Selenium server and run your tests against any browser you wish.
開始するには、アプリケーションのベースDuskテストケースである、tests/DuskTestCase.php
ファイルを開きます。このファイルの中の、startChromeDriver
メソッド呼び出しを削除してください。これにより、ChromeDriverの自動起動を停止します。To get started, open your tests/DuskTestCase.php
file, which is the base Dusk test case for your application. Within this file, you can remove the call to the startChromeDriver
method. This will stop Dusk from automatically starting the ChromeDriver:
/**
* Duskテスト実行準備
*
* @beforeClass
* @return void
*/
public static function prepare()
{
// static::startChromeDriver();
}
次に、皆さんが選んだURLとポートへ接続するために、driver
メソッドを変更します。WebDriverに渡すべき、"desired capabilities"を更新することもできます。Next, you may modify the driver
method to connect to the URL and port of your choice. In addition, you may modify the "desired capabilities" that should be passed to the WebDriver:
/**
* RemoteWebDriverインスタンスの生成
*
* @return \Facebook\WebDriver\Remote\RemoteWebDriver
*/
protected function driver()
{
return RemoteWebDriver::create(
'http://localhost:4444/wd/hub', DesiredCapabilities::phantomjs()
);
}
利用の開始Getting Started
テストの生成Generating Tests
Duskのテストを生成するには、dusk:make
Artisanコマンドを使います。生成されたテストは、tests/Browser
ディレクトリへ設置されます。To generate a Dusk test, use the dusk:make
Artisan command. The generated test will be placed in the tests/Browser
directory:
php artisan dusk:make LoginTest
テストの実行Running Tests
ブラウザテストを実行するには、dusk
Artisanコマンドを使用します。To run your browser tests, use the dusk
Artisan command:
php artisan dusk
dusk
コマンドで最後に実行したテストが失敗した場合、dusk:fails
コマンドを使用し、失敗したテストを再実行することにより、時間を節約できます。If you had test failures the last time you ran the dusk
command, you may save time by re-running the failing tests first using the dusk:fails
command:
php artisan dusk:fails
PHPUnitテストランナが通常受け付ける引数は、dusk
コマンドでも指定できます。たとえば、指定したグループのテストのみを実行するなどです。The dusk
command accepts any argument that is normally accepted by the PHPUnit test runner, allowing you to only run the tests for a given group[https://phpunit.de/manual/current/en/appendixes.annotations.html#appendixes.annotations.group], etc:
php artisan dusk --group=foo
ChromeDriverの手動起動Manually Starting ChromeDriver
デフォルトのDuskは、ChromeDriverを自動的に起動しようとします。特定のシステムで自動起動しない場合は、dusk
コマンドを実行する前に手動でChromeDriverを起動することもできます。ChromeDriverを手動起動する場合は、tests/DuskTestCase.php
ファイルの以下の行をコメントアウトしてください。By default, Dusk will automatically attempt to start ChromeDriver. If this does not work for your particular system, you may manually start ChromeDriver before running the dusk
command. If you choose to start ChromeDriver manually, you should comment out the following line of your tests/DuskTestCase.php
file:
/**
* Duskテスト実行準備
*
* @beforeClass
* @return void
*/
public static function prepare()
{
// static::startChromeDriver();
}
また、ChromeDriverを9515以外のポートで起動した場合、同じクラスのdriver
メソッドを変更する必要があります。In addition, if you start ChromeDriver on a port other than 9515, you should modify the driver
method of the same class:
/**
* RemoteWebDriverインスタンスの生成
*
* @return \Facebook\WebDriver\Remote\RemoteWebDriver
*/
protected function driver()
{
return RemoteWebDriver::create(
'http://localhost:9515', DesiredCapabilities::chrome()
);
}
環境の処理Environment Handling
テスト実行時に独自の環境ファイルを強制的に使用させるには、プロジェクトのルートに.env.dusk.{environment}
ファイルを作成します。たとえば、local
環境からdusk
コマンドを起動する場合は、.env.dusk.local
ファイルを作成します。To force Dusk to use its own environment file when running tests, create a .env.dusk.{environment}
file in the root of your project. For example, if you will be initiating the dusk
command from your local
environment, you should create a .env.dusk.local
file.
テストを実行すると、Duskは.env
ファイルをバックアップし、皆さんのDusk環境を.env
へリネームします。テストが完了したら、.env
ファイルをリストアします。When running tests, Dusk will back-up your .env
file and rename your Dusk environment to .env
. Once the tests have completed, your .env
file will be restored.
ブラウザの生成Creating Browsers
手始めに、アプリケーションへログインできることを確認するテストを書いてみましょう。テストを生成したら、ログインページへ移動し、認証情報を入力し、"Login"ボタンをクリックするように変更します。ブラウザインスタンスを生成するには、browser
メソッドを呼び出します。To get started, let's write a test that verifies we can log into our application. After generating a test, we can modify it to navigate to the login page, enter some credentials, and click the "Login" button. To create a browser instance, call the browse
method:
<?php
namespace Tests\Browser;
use App\User;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Laravel\Dusk\Chrome;
use Tests\DuskTestCase;
class ExampleTest extends DuskTestCase
{
use DatabaseMigrations;
/**
* 基本的なブラウザテスト例
*
* @return void
*/
public function testBasicExample()
{
$user = factory(User::class)->create([
'email' => 'taylor@laravel.com',
]);
$this->browse(function ($browser) use ($user) {
$browser->visit('/login')
->type('email', $user->email)
->type('password', 'password')
->press('Login')
->assertPathIs('/home');
});
}
}
上記の例のように、browse
メソッドはコールバックを引数に受けます。 Duskによりブラウザインスタンスは自動的にこのコールバックに渡され、このオブジェクトで、アプリケーションに対する操作やアサートを行います。As you can see in the example above, the browse
method accepts a callback. A browser instance will automatically be passed to this callback by Dusk and is the main object used to interact with and make assertions against your application.
複数ブラウザの生成Creating Multiple Browsers
テストを行うために複数のブラウザが必要なこともあります。たとえば、Webソケットを使用するチャットスクリーンをテストするためには、複数のブラウザが必要でしょう。複数ブラウザを生成するには、browse
メソッドに指定するコールバックの引数で、一つ以上のブラウザを指定します。Sometimes you may need multiple browsers in order to properly carry out a test. For example, multiple browsers may be needed to test a chat screen that interacts with websockets. To create multiple browsers, "ask" for more than one browser in the signature of the callback given to the browse
method:
$this->browse(function ($first, $second) {
$first->loginAs(User::find(1))
->visit('/home')
->waitForText('Message');
$second->loginAs(User::find(2))
->visit('/home')
->waitForText('Message')
->type('message', 'Hey Taylor')
->press('Send');
$first->waitForText('Hey Taylor')
->assertSee('Jeffrey Way');
});
ブラウザウィンドウのリサイズResizing Browser Windows
ブラウザウインドウのサイズを調整するため、resize
メソッドを使用できます。You may use the resize
method to adjust the size of the browser window:
$browser->resize(1920, 1080);
ブラウザウィンドウを最大化するには、maximize
メソッドを使います。The maximize
method may be used to maximize the browser window:
$browser->maximize();
fitContent
メソッドは、コンテンツに合わせてブラウザウィンドウのサイズをリサイズします。The fitContent
method will resize the browser window to match the size of the content:
$browser->fitContent();
テスト失敗時にDuskはスクリーンショットを取るために、以前のコンテンツに合うようブラウザを自動的にリサイズします。この機能を無効にするには、テストの中でdisableFitOnFailure
メソッドを呼び出してください。When a test fails, Dusk will automatically resize the browser to fit the content prior to taking a screenshot. You may disable this feature by calling the disableFitOnFailure
method within your test:
$browser->disableFitOnFailure();
ブラウザマクロBrowser Macros
さまざまなテストで再利用可能な、カスタムブラウザメソッドを定義したい場合は、Browser
クラスのmacro
メソッドを使用してください。If you would like to define a custom browser method that you can re-use in a variety of your tests, you may use the macro
method on the Browser
class. Typically, you should call this method from a service provider's[/docs/{{version}}/providers] boot
method:
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Laravel\Dusk\Browser;
class DuskServiceProvider extends ServiceProvider
{
/**
* Duskのブラウザマクロの登録
*
* @return void
*/
public function boot()
{
Browser::macro('scrollToElement', function ($element = null) {
$this->script("$('html, body').animate({ scrollTop: $('$element').offset().top }, 0);");
return $this;
});
}
}
macro
関数の第1引数は名前で、第2引数はクロージャです。このクロージャは、Browser
実装上でメソッドとしてマクロが呼び出された時に、実行されます。The macro
function accepts a name as its first argument, and a Closure as its second. The macro's Closure will be executed when calling the macro as a method on a Browser
implementation:
$this->browse(function ($browser) use ($user) {
$browser->visit('/pay')
->scrollToElement('#credit-card-details')
->assertSee('Enter Credit Card Details');
});
認証Authentication
認証が必要なページのテストはよくあります。毎回テストのたびにログインスクリーンを操作しなくても済むように、DuskのloginAs
メソッドを使ってください。loginAs
メソッドはユーザーIDかユーザーモデルインスタンスを引数に取ります。Often, you will be testing pages that require authentication. You can use Dusk's loginAs
method in order to avoid interacting with the login screen during every test. The loginAs
method accepts a user ID or user model instance:
$this->browse(function ($first, $second) {
$first->loginAs(User::find(1))
->visit('/home');
});
Note:
loginAs
メソッドを使用後、そのファイルに含まれるすべてのテストに対し、ユーザーセッションは保持されます。{note} After using theloginAs
method, the user session will be maintained for all tests within the file.
データベースマイグレーションDatabase Migrations
上記の認証サンプルのように、マイグレーションをテストする必要がある場合は、RefreshDatabase
トレイトを使用してはいけません。RefreshDatabase
トレイトはHTTPリクエストに対し適用されない、データベーストランザクションに活用します。代わりに、DatabaseMigrations
トレイトを使用してください。When your test requires migrations, like the authentication example above, you should never use the RefreshDatabase
trait. The RefreshDatabase
trait leverages database transactions which will not be applicable across HTTP requests. Instead, use the DatabaseMigrations
trait:
<?php
namespace Tests\Browser;
use App\User;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Laravel\Dusk\Chrome;
use Tests\DuskTestCase;
class ExampleTest extends DuskTestCase
{
use DatabaseMigrations;
}
要素の操作Interacting With Elements
DuskセレクタDusk Selectors
要素を操作するために、最適なCSSセレクタを選択するのは、Duskテストで一番難しい部分です。フロントエンドは繰り返し変更され、失敗するようになったテストを修正するため、CSSセレクタを何度も調整しました。Choosing good CSS selectors for interacting with elements is one of the hardest parts of writing Dusk tests. Over time, frontend changes can cause CSS selectors like the following to break your tests:
// HTML
<button>Login</button>
// テスト
$browser->click('.login-page .container div > button');
Duskセレクタにより、CSSセレクタを記憶せず効率的にテストを書くことへ集中できるようになります。セレクタを定義するには、HTML要素にdusk
属性を追加します。それから、Duskテスト中の要素を操作するために、セレクタの先頭に@
を付けてください。Dusk selectors allow you to focus on writing effective tests rather than remembering CSS selectors. To define a selector, add a dusk
attribute to your HTML element. Then, prefix the selector with @
to manipulate the attached element within a Dusk test:
// HTML
<button dusk="login-button">Login</button>
// テスト
$browser->click('@login-button');
リンクのクリックClicking Links
リンクをクリックするには、ブラウザインスタンスのclickLink
メソッドを使います。clickLink
メソッドは指定した表示テキストのリンクをクリックします。To click a link, you may use the clickLink
method on the browser instance. The clickLink
method will click the link that has the given display text:
$browser->clickLink($linkText);
Note: {note} This method interacts with jQuery. If jQuery is not available on the page, Dusk will automatically inject it into the page so it is available for the test's duration.
このメソッドはjQueryを操作します。jQueryがそのページで使用不可能な場合、Duskは自動的にそのページへ挿入し、テストの中に使用します。
テキスト、値、属性Text, Values, & Attributes
値の取得/設定Retrieving & Setting Values
Duskは現在表示されているテキスト、値、ページ要素の属性を操作する、数多くのメソッドを提供します。たとえば、指定したセレクタに一致する要素の「値(value)」を取得するには、value
メソッドを使用します。Dusk provides several methods for interacting with the current display text, value, and attributes of elements on the page. For example, to get the "value" of an element that matches a given selector, use the value
method:
// 値の取得
$value = $browser->value('selector');
// 値の設定
$browser->value('selector', 'value');
テキストの取得Retrieving Text
text
メソッドは、指定したセレクタに一致する要素の表示テキストを取得します。The text
method may be used to retrieve the display text of an element that matches the given selector:
$text = $browser->text('selector');
属性の取得Retrieving Attributes
最後のattribute
メソッドは、セレクタに一致する要素の属性を取得します。Finally, the attribute
method may be used to retrieve an attribute of an element matching the given selector:
$attribute = $browser->attribute('selector', 'value');
フォームの使用Using Forms
値のタイプTyping Values
Duskはフォームと入力要素を操作する、さまざまなメソッドを提供しています。最初に、入力フィールドへテキストをタイプする例を見てみましょう。Dusk provides a variety of methods for interacting with forms and input elements. First, let's take a look at an example of typing text into an input field:
$browser->type('email', 'taylor@laravel.com');
必要であれば受け付けますが、type
メソッドにはCSSセレクタを渡す必要がないことに注意してください。CSSセレクタが指定されない場合、Duskはname
属性に指定された入力フィールドを探します。最終的に、Duskは指定されたname
属性を持つtextarea
を見つけようとします。Note that, although the method accepts one if necessary, we are not required to pass a CSS selector into the type
method. If a CSS selector is not provided, Dusk will search for an input field with the given name
attribute. Finally, Dusk will attempt to find a textarea
with the given name
attribute.
コンテンツをクリアせずに、フィールドへテキストを追加するには、append
メソッドを使用します。To append text to a field without clearing its content, you may use the append
method:
$browser->type('tags', 'foo')
->append('tags', ', bar, baz');
入力値をクリアするには、clear
メソッドを使用します。You may clear the value of an input using the clear
method:
$browser->clear('email');
ドロップダウンDropdowns
ドロップダウンの選択ボックスから値を選ぶには、select
メソッドを使います。type
メソッドと同様に、select
メソッドも完全なCSSセレクタは必要ありません。select
メソッドに引数を指定するとき、表示テキストの代わりに、オプション値を渡します。To select a value in a dropdown selection box, you may use the select
method. Like the type
method, the select
method does not require a full CSS selector. When passing a value to the select
method, you should pass the underlying option value instead of the display text:
$browser->select('size', 'Large');
第2引数を省略した場合、ランダムにオプションを選択します。You may select a random option by omitting the second parameter:
$browser->select('size');
チェックボックスCheckboxes
チェックボックスを「チェック(check)」するには、check
メソッドを使います。他の関連する多くのメソッドと同様に、完全なCSSセレクタは必要ありません。完全に一致するセレクタが見つからないと、Duskはname
属性に一致するチェックボックスを探します。To "check" a checkbox field, you may use the check
method. Like many other input related methods, a full CSS selector is not required. If an exact selector match can't be found, Dusk will search for a checkbox with a matching name
attribute:
$browser->check('terms');
$browser->uncheck('terms');
ラジオボタンRadio Buttons
ラジオボタンのオプションを「選択」するには、radio
メソッドを使用します。他の関連する多くのメソッドと同様に、完全なセレクタは必要ありません。完全に一致するセレクタが見つからない場合、Duskはname
とvalue
属性に一致するラジオボタンを探します。To "select" a radio button option, you may use the radio
method. Like many other input related methods, a full CSS selector is not required. If an exact selector match can't be found, Dusk will search for a radio with matching name
and value
attributes:
$browser->radio('version', 'php7');
添付ファイルAttaching Files
attach
メソッドはfile
入力要素で、ファイルを指定するために使用します。他の関連する入力メソッドと同様に、完全なCSSセレクタは必要ありません。完全なセレクタが見つからなければ、Duskはname
属性と一致するファイル入力を探します。The attach
method may be used to attach a file to a file
input element. Like many other input related methods, a full CSS selector is not required. If an exact selector match can't be found, Dusk will search for a file input with matching name
attribute:
$browser->attach('photo', __DIR__.'/photos/me.png');
Note:
attach
関数を利用するには、サーバへZip
PHP拡張をインストールし、有効にする必要があります。{note} The attach function requires theZip
PHP extension to be installed and enabled on your server.
キーワードの使用Using The Keyboard
keys
メソッドは、type
メソッドによる、指定した要素に対する通常の入力よりも、複雑な入力を提供します。たとえば、モデファイヤキーを押しながら、値を入力するなどです。以下の例では、指定したセレクタに一致する要素へ、taylor
を「シフト(shift
)」キーを押しながら入力します。Taylor
をタイプし終えると、otwell
がモデファイヤキーを押さずにタイプされます。The keys
method allows you to provide more complex input sequences to a given element than normally allowed by the type
method. For example, you may hold modifier keys entering values. In this example, the shift
key will be held while taylor
is entered into the element matching the given selector. After taylor
is typed, otwell
will be typed without any modifier keys:
$browser->keys('selector', ['{shift}', 'taylor'], 'otwell');
アプリケーションを構成する主要なCSSセレクタへ「ホットキー」を送ることもできます。You may even send a "hot key" to the primary CSS selector that contains your application:
$browser->keys('.app', ['{command}', 'j']);
">Tip!! モデファイヤキーは
{}
文字で囲み、Facebook\WebDriver\WebDriverKeys
クラスで定義されている定数を指定します。GitHubで確認できます。{tip} All modifier keys are wrapped in{}
characters, and match the constants defined in theFacebook\WebDriver\WebDriverKeys
class, which can be found on GitHub[https://github.com/php-webdriver/php-webdriver/blob/master/lib/WebDriverKeys.php].
マウスの使用Using The Mouse
要素のクリックClicking On Elements
指定したセレクタに一致する要素を「クリック」するには、click
メソッドを使います。The click
method may be used to "click" on an element matching the given selector:
$browser->click('.selector');
マウスオーバーMouseover
指定したセレクタに一致する要素を「マウスオーバー」したい場合は、mouseover
メソッドを使います。The mouseover
method may be used when you need to move the mouse over an element matching the given selector:
$browser->mouseover('.selector');
ドラッグ&ドロップDrag & Drop
drag
メソッドは指定したセレクタに一致する要素をドラッグし、もう一つの要素へドロップします。The drag
method may be used to drag an element matching the given selector to another element:
$browser->drag('.from-selector', '.to-selector');
もしくは、特定の方向へ要素をドラッグすることもできます。Or, you may drag an element in a single direction:
$browser->dragLeft('.selector', 10);
$browser->dragRight('.selector', 10);
$browser->dragUp('.selector', 10);
$browser->dragDown('.selector', 10);
JavaScriptダイアログJavaScript Dialogs
DuskはJavaScriptダイアログを操作する、さまざまなメソッドを提供しています。Dusk provides various methods to interact with JavaScript Dialogs:
// ダイアログが表示されるのを待つ
$browser->waitForDialog($seconds = null);
// ダイアログが表示され、メッセージが指定した値と一致することを宣言
$browser->assertDialogOpened('value');
// 開いているJavaScript入力(prompt)ダイアログに、指定値をタイプ
$browser->typeInDialog('Hello World');
開いているJavaScriptダイアログをOKボタンのクリックで閉じるには:To close an opened JavaScript Dialog, clicking the OK button:
$browser->acceptDialog();
開いているJavaScriptダイアログをキャンセルボタンのクリックで閉じるには(確認ダイアログのみ):To close an opened JavaScript Dialog, clicking the Cancel button (for a confirmation dialog only):
$browser->dismissDialog();
セレクタの範囲指定Scoping Selectors
特定のセレクタの中の全操作を範囲指定しつつ、多くの操作を行いたいこともあります。たとえば、いくつかのテーブル中にあるテキストが存在していることをアサートし、それからテーブル中のボタンをクリックしたい場合です。with
メソッドで行なえます。with
メソッドのコールバック中で行われた操作は全部、オリジナルのセレクタに対し限定されます。Sometimes you may wish to perform several operations while scoping all of the operations within a given selector. For example, you may wish to assert that some text exists only within a table and then click a button within that table. You may use the with
method to accomplish this. All operations performed within the callback given to the with
method will be scoped to the original selector:
$browser->with('.table', function ($table) {
$table->assertSee('Hello World')
->clickLink('Delete');
});
要素の待機Waiting For Elements
広範囲に渡りJavaScriptを使用しているアプリケーションのテストでは、テストを進める前に特定の要素やデータが利用可能になるまで、「待つ(wait)」必要がしばしば起きます。Duskではこれも簡単に行えます。数多くのメソッドを使い、ページで要素が見えるようになるまで、もしくはJavaScriptの評価がtrue
になるまで待機できます。When testing applications that use JavaScript extensively, it often becomes necessary to "wait" for certain elements or data to be available before proceeding with a test. Dusk makes this a cinch. Using a variety of methods, you may wait for elements to be visible on the page or even wait until a given JavaScript expression evaluates to true
.
待機Waiting
指定したミリ秒の間、テストをポーズしたい場合は、pause
メソッドを使用します。If you need to pause the test for a given number of milliseconds, use the pause
method:
$browser->pause(1000);
セレクタの待機Waiting For Selectors
waitFor
メソッドはテストの実行を指定したCSSセレクタがページに表示されるまで中断します。例外が投げられるまで、デフォルトで最大5秒間テストを中断します。必要であれば、カスタムタイムアウトを秒でメソッドの第2引数として指定できます。The waitFor
method may be used to pause the execution of the test until the element matching the given CSS selector is displayed on the page. By default, this will pause the test for a maximum of five seconds before throwing an exception. If necessary, you may pass a custom timeout threshold as the second argument to the method:
// セレクタを最大5秒間待つ
$browser->waitFor('.selector');
// セレクタを最大1秒待つ
$browser->waitFor('.selector', 1);
指定したセレクタがページから消えるまで待つこともできます。You may also wait until the given selector is missing from the page:
$browser->waitUntilMissing('.selector');
$browser->waitUntilMissing('.selector', 1);
利用可能時限定のセレクタScoping Selectors When Available
指定したセレクタを待ち、それからそのセレクタに一致する要素を操作したい場合もよくあります。たとえば、モーダルウィンドウが現れるまで待ち、それからそのモーダルウィンドウ上の"OK"ボタンを押したい場合です。このケースではwhenAvailable
メソッドを使用します。指定したコールバック内で行われた要素操作はすべて、オリジナルのセレクタに対して限定されます。Occasionally, you may wish to wait for a given selector and then interact with the element matching the selector. For example, you may wish to wait until a modal window is available and then press the "OK" button within the modal. The whenAvailable
method may be used in this case. All element operations performed within the given callback will be scoped to the original selector:
$browser->whenAvailable('.modal', function ($modal) {
$modal->assertSee('Hello World')
->press('OK');
});
テキストの待機Waiting For Text
指定したテキストがページに表示されるまで待ちたい場合は、waitForText
メソッドを使います。The waitForText
method may be used to wait until the given text is displayed on the page:
// テキストを最大5秒間待つ
$browser->waitForText('Hello World');
// テキストを最大1秒待つ
$browser->waitForText('Hello World', 1);
ページに表示されている指定したテキストが削除されるまで待ちたい場合は、waitUntilMissingText
メソッドを使います。You may use the waitUntilMissingText
method to wait until the displayed text has been removed from the page:
// テキストが削除されるまで最大5秒間待つ
$browser->waitUntilMissingText('Hello World');
// テキストが削除されるまで最大1秒間待つ
$browser->waitUntilMissingText('Hello World', 1);
リンクの待機Waiting For Links
ページに指定したリンクテキストが表示されるまで待つ場合は、waitForLink
メソッドを使います。The waitForLink
method may be used to wait until the given link text is displayed on the page:
// リンクを最大5秒間待つ
$browser->waitForLink('Create');
// リンクを最大1秒間待つ
$browser->waitForLink('Create', 1);
ページロケーションの待機Waiting On The Page Location
$browser->assertPathIs('/home')
のようなパスをアサートするときに、window.location.pathname
が非同期更新中の場合、アサートは失敗するでしょう。指定値のロケーションを待機するために、waitForLocation
メソッドを使ってください。When making a path assertion such as $browser->assertPathIs('/home')
, the assertion can fail if window.location.pathname
is being updated asynchronously. You may use the waitForLocation
method to wait for the location to be a given value:
$browser->waitForLocation('/secret');
名前付きルートのロケーションを待機することも可能です。You may also wait for a named route's location:
$browser->waitForRoute($routeName, $parameters);
ページリロードの待機Waiting for Page Reloads
ページのリロード後にアサートする必要がある場合は、waitForReload
メソッドを使ってください。If you need to make assertions after a page has been reloaded, use the waitForReload
method:
$browser->click('.some-action')
->waitForReload()
->assertSee('something');
JavaScriptの評価の待機Waiting On JavaScript Expressions
指定したJavaScript式の評価がtrue
になるまで、テストの実行を中断したい場合もときどきあります。waitUntil
メソッドで簡単に行えます。このメソッドに式を渡す時に、return
キーワードや最後のセミコロンを含める必要はありません。Sometimes you may wish to pause the execution of a test until a given JavaScript expression evaluates to true
. You may easily accomplish this using the waitUntil
method. When passing an expression to this method, you do not need to include the return
keyword or an ending semi-colon:
// 式がtrueになるまで最大5秒間待つ
$browser->waitUntil('App.dataLoaded');
$browser->waitUntil('App.data.servers.length > 0');
// 式がtrueになるまで最大1秒間待つ
$browser->waitUntil('App.data.servers.length > 0', 1);
Vue式でwaitするWaiting On Vue Expressions
以下のメソッドで、特定のVueコンポーネント属性が、指定値になるまで待つことができます。The following methods may be used to wait until a given Vue component attribute has a given value:
// 指定したコンポーネント属性が、指定値を含むまで待つ
$browser->waitUntilVue('user.name', 'Taylor', '@user');
// 指定したコンポーネント属性が、指定値を含まなくなるまで待つ
$browser->waitUntilVueIsNot('user.name', null, '@user');
コールバックによる待機Waiting With A Callback
Duskにある数多くの「待機」メソッドは、waitUsing
メソッドを使用しています。このメソッドを直接利用し、コールバックがtrue
を返すまで待機できます。waitUsing
メソッドは最長待ち秒数とクロージャを評価する間隔秒数、クロージャを引数に取ります。オプションとして、失敗時のメッセージを引数に取ります。Many of the "wait" methods in Dusk rely on the underlying waitUsing
method. You may use this method directly to wait for a given callback to return true
. The waitUsing
method accepts the maximum number of seconds to wait, the interval at which the Closure should be evaluated, the Closure, and an optional failure message:
$browser->waitUsing(10, 1, function () use ($something) {
return $something->isReady();
}, "Something wasn't ready in time.");
Vueアサーションの作成Making Vue Assertions
Duskでは、Vueコンポーネントデータの状態をアサートすることもできます。たとえば、アプリケーションに以下のVueコンポーネントが含まれていると想像してください。Dusk even allows you to make assertions on the state of Vue[https://vuejs.org] component data. For example, imagine your application contains the following Vue component:
// HTML
<profile dusk="profile-component"></profile>
// コンポーネント定義
Vue.component('profile', {
template: '<div>{{ user.name }}</div>',
data: function () {
return {
user: {
name: 'Taylor'
}
};
}
});
Vueコンポーネントの状態を以下のようにアサートできます。You may assert on the state of the Vue component like so:
/**
* 基本的なVueのテスト
*
* @return void
*/
public function testVue()
{
$this->browse(function (Browser $browser) {
$browser->visit('/')
->assertVue('user.name', 'Taylor', '@profile-component');
});
}
使用可能なアサートAvailable Assertions
Duskはアプリケーションに対する数多くのアサートを提供しています。使用できるアサートを以下のリストにまとめます。Dusk provides a variety of assertions that you may make against your application. All of the available assertions are documented in the list below:
assertTitleassertTitle
ページタイトルが指定した文字列と一致することを宣言します。Assert that the page title matches the given text:
$browser->assertTitle($title);
assertTitleContainsassertTitleContains
ページタイトルに、指定したテキストが含まれていることを宣言します。Assert that the page title contains the given text:
$browser->assertTitleContains($title);
assertUrlIsassertUrlIs
クエリ文字列を除いた、現在のURLが指定した文字列と一致するのを宣言します。Assert that the current URL (without the query string) matches the given string:
$browser->assertUrlIs($url);
assertSchemeIsassertSchemeIs
現在のURLスキームが、指定したスキームと一致することを宣言します。Assert that the current URL scheme matches the given scheme:
$browser->assertSchemeIs($scheme);
assertSchemeIsNotassertSchemeIsNot
現在のURLスキームが、指定したスキームと一致しないことを宣言します。Assert that the current URL scheme does not match the given scheme:
$browser->assertSchemeIsNot($scheme);
assertHostIsassertHostIs
現在のURLのホストが、指定したホストと一致することを宣言します。Assert that the current URL host matches the given host:
$browser->assertHostIs($host);
assertHostIsNotassertHostIsNot
現在のURLのホストが、指定したホストと一致しないことを宣言します。Assert that the current URL host does not match the given host:
$browser->assertHostIsNot($host);
assertPortIsassertPortIs
現在のURLポートが、指定したポートと一致することを宣言します。Assert that the current URL port matches the given port:
$browser->assertPortIs($port);
assertPortIsNotassertPortIsNot
現在のURLポートが、指定したポートと一致しないことを宣言します。Assert that the current URL port does not match the given port:
$browser->assertPortIsNot($port);
assertPathBeginsWithassertPathBeginsWith
現在のURLパスが指定したパスで始まることを宣言します。Assert that the current URL path begins with the given path:
$browser->assertPathBeginsWith($path);
assertPathIsassertPathIs
現在のパスが指定したパスであることを宣言します。Assert that the current path matches the given path:
$browser->assertPathIs('/home');
assertPathIsNotassertPathIsNot
現在のパスが指定したパスではないことを宣言します。Assert that the current path does not match the given path:
$browser->assertPathIsNot('/home');
assertRouteIsassertRouteIs
現在のURLが指定した名前付きルートのURLと一致することを宣言します。Assert that the current URL matches the given named route's URL:
$browser->assertRouteIs($name, $parameters);
assertQueryStringHasassertQueryStringHas
指定したクエリ文字列パラメータが存在していることを宣言します。Assert that the given query string parameter is present:
$browser->assertQueryStringHas($name);
指定したクエリ文字列パラメータが存在し、指定値を持っていることを宣言します。Assert that the given query string parameter is present and has a given value:
$browser->assertQueryStringHas($name, $value);
assertQueryStringMissingassertQueryStringMissing
指定した文字列パラメータが存在しないことを宣言します。Assert that the given query string parameter is missing:
$browser->assertQueryStringMissing($name);
assertFragmentIsassertFragmentIs
現在のフラグメントが、指定したフラグメントと一致することを宣言します。Assert that the current fragment matches the given fragment:
$browser->assertFragmentIs('anchor');
assertFragmentBeginsWithassertFragmentBeginsWith
現在のフラグメントが、指定したフラグメントで始まることを宣言します。Assert that the current fragment begins with the given fragment:
$browser->assertFragmentBeginsWith('anchor');
assertFragmentIsNotassertFragmentIsNot
現在のフラグメントが、指定したフラグメントと一致しないことを宣言します。Assert that the current fragment does not match the given fragment:
$browser->assertFragmentIsNot('anchor');
assertHasCookieassertHasCookie
指定したクッキーが存在していることを宣言します。Assert that the given cookie is present:
$browser->assertHasCookie($name);
assertCookieMissingassertCookieMissing
指定したクッキーが存在していないことを宣言します。Assert that the given cookie is not present:
$browser->assertCookieMissing($name);
assertCookieValueassertCookieValue
クッキーが指定値を持っていることを宣言します。Assert that a cookie has a given value:
$browser->assertCookieValue($name, $value);
assertPlainCookieValueassertPlainCookieValue
暗号化されていないクッキーが、指定値を持っていることを宣言します。Assert that an unencrypted cookie has a given value:
$browser->assertPlainCookieValue($name, $value);
assertSeeassertSee
指定したテキストが、ページ上に存在することを宣言します。Assert that the given text is present on the page:
$browser->assertSee($text);
assertDontSeeassertDontSee
指定したテキストが、ページ上に存在しないことを宣言します。Assert that the given text is not present on the page:
$browser->assertDontSee($text);
assertSeeInassertSeeIn
指定したテキストが、セレクタに含まれていることを宣言します。Assert that the given text is present within the selector:
$browser->assertSeeIn($selector, $text);
assertDontSeeInassertDontSeeIn
指定したテキストが、セレクタに含まれていないことを宣言します。Assert that the given text is not present within the selector:
$browser->assertDontSeeIn($selector, $text);
assertSourceHasassertSourceHas
指定したソースコードが、ページ上に存在していることを宣言します。Assert that the given source code is present on the page:
$browser->assertSourceHas($code);
assertSourceMissingassertSourceMissing
指定したソースコードが、ページ上に存在していないことを宣言します。Assert that the given source code is not present on the page:
$browser->assertSourceMissing($code);
assertSeeLinkassertSeeLink
指定したリンクが、ページ上に存在していることを宣言します。Assert that the given link is present on the page:
$browser->assertSeeLink($linkText);
assertDontSeeLinkassertDontSeeLink
指定したリンクが、ページ上に存在していないことを宣言します。Assert that the given link is not present on the page:
$browser->assertDontSeeLink($linkText);
assertInputValueassertInputValue
指定した入力フィールドが、指定値を持っていることを宣言します。Assert that the given input field has the given value:
$browser->assertInputValue($field, $value);
assertInputValueIsNotassertInputValueIsNot
指定した入力フィールドが、指定値を持っていないことを宣言します。Assert that the given input field does not have the given value:
$browser->assertInputValueIsNot($field, $value);
assertCheckedassertChecked
指定したチェックボックスが、チェック済みであることを宣言します。Assert that the given checkbox is checked:
$browser->assertChecked($field);
assertNotCheckedassertNotChecked
指定したチェックボックスが、チェックされていないことを宣言します。Assert that the given checkbox is not checked:
$browser->assertNotChecked($field);
assertRadioSelectedassertRadioSelected
指定したラジオフィールドが選択されていることを宣言します。Assert that the given radio field is selected:
$browser->assertRadioSelected($field, $value);
assertRadioNotSelectedassertRadioNotSelected
指定したラジオフィールドが選択されていないことを宣言します。Assert that the given radio field is not selected:
$browser->assertRadioNotSelected($field, $value);
assertSelectedassertSelected
指定したドロップダウンで指定値が選択されていることを宣言します。Assert that the given dropdown has the given value selected:
$browser->assertSelected($field, $value);
assertNotSelectedassertNotSelected
指定したドロップダウンで指定値が選択されていないことを宣言します。Assert that the given dropdown does not have the given value selected:
$browser->assertNotSelected($field, $value);
assertSelectHasOptionsassertSelectHasOptions
指定した配列値が選択可能であることを宣言します。Assert that the given array of values are available to be selected:
$browser->assertSelectHasOptions($field, $values);
assertSelectMissingOptionsassertSelectMissingOptions
指定した配列値が選択不可であることを宣言します。Assert that the given array of values are not available to be selected:
$browser->assertSelectMissingOptions($field, $values);
assertSelectHasOptionassertSelectHasOption
指定したフィールドで、指定した値が選択可能であることを宣言します。Assert that the given value is available to be selected on the given field:
$browser->assertSelectHasOption($field, $value);
assertValueassertValue
指定したセレクタに一致する要素が、指定値であることを宣言します。Assert that the element matching the given selector has the given value:
$browser->assertValue($selector, $value);
assertVisibleassertVisible
指定したセレクタに一致する要素が、ビジブルであることを宣言します。Assert that the element matching the given selector is visible:
$browser->assertVisible($selector);
assertPresentassertPresent
指定したセレクタに一致する要素が、存在することを宣言します。Assert that the element matching the given selector is present:
$browser->assertPresent($selector);
assertMissingassertMissing
指定したセレクタに一致する要素が、ビジブルでないことを宣言します。Assert that the element matching the given selector is not visible:
$browser->assertMissing($selector);
assertDialogOpenedassertDialogOpened
指定したメッセージを持つ、JavaScriptダイアログが開かれていることを宣言します。Assert that a JavaScript dialog with the given message has been opened:
$browser->assertDialogOpened($message);
assertEnabledassertEnabled
指定したフィールドが、enabledであることを宣言します。Assert that the given field is enabled:
$browser->assertEnabled($field);
assertDisabledassertDisabled
指定したフィールドが、disabledであることを宣言します。Assert that the given field is disabled:
$browser->assertDisabled($field);
assertButtonEnabledassertButtonEnabled
指定したボタンが、enabledであることを宣言します。Assert that the given button is enabled:
$browser->assertButtonEnabled($button);
assertButtonDisabledassertButtonDisabled
指定したボタンが、disabledであることを宣言します。Assert that the given button is disabled:
$browser->assertButtonDisabled($button);
assertFocusedassertFocused
指定したフィールドに、フォーカスがあることを宣言します。Assert that the given field is focused:
$browser->assertFocused($field);
assertNotFocusedassertNotFocused
指定したフィールドから、フォーカスが外れていることを宣言します。Assert that the given field is not focused:
$browser->assertNotFocused($field);
assertVueassertVue
指定したVueコンポーネントのデータプロパティが、指定値と一致することを宣言します。Assert that a given Vue component data property matches the given value:
$browser->assertVue($property, $value, $componentSelector = null);
assertVueIsNotassertVueIsNot
指定したVueコンポーネントのデータプロパティが、指定値と一致しないことを宣言します。Assert that a given Vue component data property does not match the given value:
$browser->assertVueIsNot($property, $value, $componentSelector = null);
assertVueContainsassertVueContains
指定したVueコンポーネントのデータプロパティが配列で、指定値を含むことを宣言します。Assert that a given Vue component data property is an array and contains the given value:
$browser->assertVueContains($property, $value, $componentSelector = null);
assertVueDoesNotContainassertVueDoesNotContain
指定したVueコンポーネントのデータプロパティが配列で、指定値を含まないことを宣言します。Assert that a given Vue component data property is an array and does not contain the given value:
$browser->assertVueDoesNotContain($property, $value, $componentSelector = null);
ページPages
時にテストで、連続して実行する複雑なアクションをたくさん要求されることがあります。これにより、テストは読みづらく、また理解しづらくなります。ページに対し一つのメソッドを使うだけで、指定ページで実行されるアクションを記述的に定義できます。ページはまた、アプリケーションやシングルページで一般的なセレクタの、短縮記法を定義する方法も提供しています。Sometimes, tests require several complicated actions to be performed in sequence. This can make your tests harder to read and understand. Pages allow you to define expressive actions that may then be performed on a given page using a single method. Pages also allow you to define short-cuts to common selectors for your application or a single page.
ページの生成Generating Pages
ページオプジェクトを生成するには、dusk:page
Artisanコマンドを使います。すべてのページオブジェクトは、tests/Browser/Pages
ディレクトリへ設置します。To generate a page object, use the dusk:page
Artisan command. All page objects will be placed in the tests/Browser/Pages
directory:
php artisan dusk:page Login
ページの設定Configuring Pages
デフォルトでページには、url
、assert
、elements
の3メソッドが用意されています。url
とassert
メソッドは、この後説明します。elements
メソッドについては、のちほど詳細を紹介します。By default, pages have three methods: url
, assert
, and elements
. We will discuss the url
and assert
methods now. The elements
method will be discussed in more detail below[#shorthand-selectors].
url
メソッドThe url
Method
url
メソッドでは、そのページを表すURLのパスを返します。Duskはブラウザでこのページへ移動するとき、このURLを使用します。The url
method should return the path of the URL that represents the page. Dusk will use this URL when navigating to the page in the browser:
/**
* このページのURL取得
*
* @return string
*/
public function url()
{
return '/login';
}
assert
メソッドThe assert
Method
assert
メソッドでは、ブラウザが実際に指定ページを表示した時に、確認が必要なアサーションを定義します。このメソッドで完全に行う必要はありません。ですが、もしお望みであれば自由にアサートを記述してください。記述されたアサートは、このページへ移行時に自動的に実行されます。The assert
method may make any assertions necessary to verify that the browser is actually on the given page. Completing this method is not necessary; however, you are free to make these assertions if you wish. These assertions will be run automatically when navigating to the page:
/**
* ブラウザがこのページにやって来たときのアサート
*
* @return void
*/
public function assert(Browser $browser)
{
$browser->assertPathIs($this->url());
}
ページへのナビゲーションNavigating To Pages
ページの設定を終えたら、visit
メソッドを使い、ページへ移行できます。Once a page has been configured, you may navigate to it using the visit
method:
use Tests\Browser\Pages\Login;
$browser->visit(new Login);
すでに特定のページに移動済みで、現在のテストコンテキストへそのページのセレクタとメソッドを「ロード」する必要が起き得ます。この状況は、明示的に移動していなくても、あるボタンを押すことで指定ページへリダイレクトしてしまう場合に発生します。そうした場合は、on
メソッドで、そのページをロードできます。Sometimes you may already be on a given page and need to "load" the page's selectors and methods into the current test context. This is common when pressing a button and being redirected to a given page without explicitly navigating to it. In this situation, you may use the on
method to load the page:
use Tests\Browser\Pages\CreatePlaylist;
$browser->visit('/dashboard')
->clickLink('Create Playlist')
->on(new CreatePlaylist)
->assertSee('@create');
セレクタの簡略記述Shorthand Selectors
ページのelements
メソッドにより、覚えやすいCSSセレクタの短縮形を素早く定義できます。例として、アプリケーションのログインページの"email"入力フィールドの短縮形を定義してみましょう。The elements
method of pages allows you to define quick, easy-to-remember shortcuts for any CSS selector on your page. For example, let's define a shortcut for the "email" input field of the application's login page:
/**
* ページ要素の短縮形を取得
*
* @return array
*/
public function elements()
{
return [
'@email' => 'input[name=email]',
];
}
これで、完全なCSSセレクタを指定する箇所ならどこでも、この短縮セレクタを使用できます。Now, you may use this shorthand selector anywhere you would use a full CSS selector:
$browser->type('@email', 'taylor@laravel.com');
グローバルなセレクタ簡略記述Global Shorthand Selectors
Duskをインストールすると、ベースPage
クラスがtests/Browser/Pages
ディレクトリへ設置されます。このクラスは、アプリケーション全部のどのページからでも利用可能な、グローバル短縮セレクタを定義するsiteElements
メソッドを含んでいます。After installing Dusk, a base Page
class will be placed in your tests/Browser/Pages
directory. This class contains a siteElements
method which may be used to define global shorthand selectors that should be available on every page throughout your application:
/**
* サイトのグローバル要素短縮形の取得
*
* @return array
*/
public static function siteElements()
{
return [
'@element' => '#selector',
];
}
ページメソッドPage Methods
ページに対し定義済みのデフォルトメソッドに加え、テスト全体で使用できる追加メソッドも定義できます。たとえば、音楽管理アプリケーションを構築中だと想像してみましょう。アプリケーションのあるページでプレイリストを作成するのは、よくあるアクションです。各テストごとにプレイリスト作成のロジックを書き直す代わりに、ページクラスにcreatePlaylist
メソッドを定義できます。In addition to the default methods defined on pages, you may define additional methods which may be used throughout your tests. For example, let's imagine we are building a music management application. A common action for one page of the application might be to create a playlist. Instead of re-writing the logic to create a playlist in each test, you may define a createPlaylist
method on a page class:
<?php
namespace Tests\Browser\Pages;
use Laravel\Dusk\Browser;
class Dashboard extends Page
{
// 他のページメソッドの定義…
/**
* 新しいプレイリストの作成
*
* @param \Laravel\Dusk\Browser $browser
* @param string $name
* @return void
*/
public function createPlaylist(Browser $browser, $name)
{
$browser->type('name', $name)
->check('share')
->press('Create Playlist');
}
}
メソッドを定義すれば、このページを使用するすべてのテストの中で使用できます。ブラウザインスタンスは自動的にページメソッドへ渡されます。Once the method has been defined, you may use it within any test that utilizes the page. The browser instance will automatically be passed to the page method:
use Tests\Browser\Pages\Dashboard;
$browser->visit(new Dashboard)
->createPlaylist('My Playlist')
->assertSee('My Playlist');
コンポーネントComponents
コンポーネントはDuskの「ページオブジェクト」と似ていますが、ナビゲーションバーや通知ウィンドウのような、UI群と機能をアプリケーション全体で再利用するためのものです。コンポーネントは特定のURLと結びついていません。Components are similar to Dusk’s “page objects”, but are intended for pieces of UI and functionality that are re-used throughout your application, such as a navigation bar or notification window. As such, components are not bound to specific URLs.
コンポーネント生成Generating Components
コンポーネントを生成するには、dusk:component
Artisanコマンドを使用します。新しいコンポーネントは、tests/Browser/Components
ディレクトリに設置されます。To generate a component, use the dusk:component
Artisan command. New components are placed in the tests/Browser/Components
directory:
php artisan dusk:component DatePicker
上記の「デートピッカー」は、アプリケーション全体のさまざまなページで利用されるコンポーネントの一例です。テストスーツ全体の何ダースものテスト中で、日付を選択するブラウザ自動化ロジックを一々書くのは大変な手間です。その代わりに、デートピッカーを表すDuskコンポーネントを定義し、そうしたロジックをコンポーネントへカプセル化できます。As shown above, a "date picker" is an example of a component that might exist throughout your application on a variety of pages. It can become cumbersome to manually write the browser automation logic to select a date in dozens of tests throughout your test suite. Instead, we can define a Dusk component to represent the date picker, allowing us to encapsulate that logic within the component:
<?php
namespace Tests\Browser\Components;
use Laravel\Dusk\Browser;
use Laravel\Dusk\Component as BaseComponent;
class DatePicker extends BaseComponent
{
/**
* コンポーネントのルートセレクタ取得
*
* @return string
*/
public function selector()
{
return '.date-picker';
}
/**
* ブラウザページにそのコンポーネントが含まれていることをアサート
*
* @param Browser $browser
* @return void
*/
public function assert(Browser $browser)
{
$browser->assertVisible($this->selector());
}
/**
* コンポーネントの要素のショートカットを取得
*
* @return array
*/
public function elements()
{
return [
'@date-field' => 'input.datepicker-input',
'@year-list' => 'div > div.datepicker-years',
'@month-list' => 'div > div.datepicker-months',
'@day-list' => 'div > div.datepicker-days',
];
}
/**
* 指定日付のセレクト
*
* @param \Laravel\Dusk\Browser $browser
* @param int $year
* @param int $month
* @param int $day
* @return void
*/
public function selectDate($browser, $year, $month, $day)
{
$browser->click('@date-field')
->within('@year-list', function ($browser) use ($year) {
$browser->click($year);
})
->within('@month-list', function ($browser) use ($month) {
$browser->click($month);
})
->within('@day-list', function ($browser) use ($day) {
$browser->click($day);
});
}
}
コンポーネントの使用Using Components
コンポーネントを定義したら、全テスト中からデートピッカーの中の指定日付を簡単にセレクトできます。日付選択で必要なロジックに変更が起きたら、このコンポーネントを更新するだけです。Once the component has been defined, we can easily select a date within the date picker from any test. And, if the logic necessary to select a date changes, we only need to update the component:
<?php
namespace Tests\Browser;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Laravel\Dusk\Browser;
use Tests\Browser\Components\DatePicker;
use Tests\DuskTestCase;
class ExampleTest extends DuskTestCase
{
/**
* 基本的なコンポーネントテスト例
*
* @return void
*/
public function testBasicExample()
{
$this->browse(function (Browser $browser) {
$browser->visit('/')
->within(new DatePicker, function ($browser) {
$browser->selectDate(2019, 1, 30);
})
->assertSee('January');
});
}
}
継続的インテグレーションContinuous Integration
Note:
持続的インテグレーション設定ファイルを追加する前に、.env.testing
ファイルへhttp://127.0.0.1:8000
の値のAPP_URL
エントリがあることを確認してください。{note} Before adding a continous integration configuration file, ensure that your.env.testing
file contains anAPP_URL
entry with a value ofhttp://127.0.0.1:8000
.
CircleCICircleCI
DustテストにCircleCIを使用する場合、以下の設定ファイルを手始めに利用できます。TravisCIと同様に、php artisan serve
コマンドを使用し、PHP組み込みWebサーバを起動できます。If you are using CircleCI to run your Dusk tests, you may use this configuration file as a starting point. Like TravisCI, we will use the php artisan serve
command to launch PHP's built-in web server:
version: 2
jobs:
build:
steps:
- run: sudo apt-get install -y libsqlite3-dev
- run: cp .env.testing .env
- run: composer install -n --ignore-platform-reqs
- run: php artisan key:generate
- run: php artisan dusk:chrome-driver
- run: npm install
- run: npm run production
- run: vendor/bin/phpunit
- run:
name: Start Chrome Driver
command: ./vendor/laravel/dusk/bin/chromedriver-linux
background: true
- run:
name: Run Laravel Server
command: php artisan serve
background: true
- run:
name: Run Laravel Dusk Tests
command: php artisan dusk
- store_artifacts:
path: tests/Browser/screenshots
CodeshipCodeship
DuskのテストをCodeshipで実行するには、以下のコマンドをCodeshipプロジェクトへ追加してください。以下のコマンドはひとつの参考例です。必要に応じて、自由にコマンドを追加してください。To run Dusk tests on Codeship[https://codeship.com], add the following commands to your Codeship project. These commands are just a starting point and you are free to add additional commands as needed:
phpenv local 7.2
cp .env.testing .env
mkdir -p ./bootstrap/cache
composer install --no-interaction --prefer-dist
php artisan key:generate
php artisan dusk:chrome-driver
nohup bash -c "php artisan serve 2>&1 &" && sleep 5
php artisan dusk
Heroku CIHeroku CI
DuskテストをHeroku CI上で実行するには、Herokuのapp.json
ファイルへ、以下のGoogle Chromeビルドパックとスクリプトを追加してください。To run Dusk tests on Heroku CI[https://www.heroku.com/continuous-integration], add the following Google Chrome buildpack and scripts to your Heroku app.json
file:
{
"environments": {
"test": {
"buildpacks": [
{ "url": "heroku/php" },
{ "url": "https://github.com/heroku/heroku-buildpack-google-chrome" }
],
"scripts": {
"test-setup": "cp .env.testing .env",
"test": "nohup bash -c './vendor/laravel/dusk/bin/chromedriver-linux > /dev/null 2>&1 &' && nohup bash -c 'php artisan serve > /dev/null 2>&1 &' && php artisan dusk"
}
}
}
}
Travis CITravis CI
Travis CI上でDuskテストを実行するためには、以降の.travis.yml
設定を使用してください。Travis CIはグラフィカルな環境ではないため、Chromeブラウザを実行するには追加の手順を行う必要があります。さらに、PHPの組み込みWebサーバを起動するために、php artisan serve
を使用する必要もあるでしょう。To run your Dusk tests on Travis CI[https://travis-ci.org], use the following .travis.yml
configuration. Since Travis CI is not a graphical environment, we will need to take some extra steps in order to launch a Chrome browser. In addition, we will use php artisan serve
to launch PHP's built-in web server:
language: php
php:
- 7.3
addons:
chrome: stable
install:
- cp .env.testing .env
- travis_retry composer install --no-interaction --prefer-dist --no-suggest
- php artisan key:generate
- php artisan dusk:chrome-driver
before_script:
- google-chrome-stable --headless --disable-gpu --remote-debugging-port=9222 http://localhost &
- php artisan serve &
script:
- php artisan dusk
GitHubアクションGitHub Actions
Duskのテスト実行にGithubアクションを使う場合は、以下の設定ファイルを手始めに利用できます。TravisCIと同様に、PHPの組み込みサーバを起動するためにphp artisan serve
コマンドが実行できます。If you are using Github Actions[https://github.com/features/actions] to run your Dusk tests, you may use this configuration file as a starting point. Like TravisCI, we will use the php artisan serve
command to launch PHP's built-in web server:
name: CI
on: [push]
jobs:
dusk-php:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Prepare The Environment
run: cp .env.example .env
- name: Create Database
run: mysql --user="root" --password="root" -e "CREATE DATABASE my-database character set UTF8mb4 collate utf8mb4_bin;"
- name: Install Composer Dependencies
run: composer install --no-progress --no-suggest --prefer-dist --optimize-autoloader
- name: Generate Application Key
run: php artisan key:generate
- name: Upgrade Chrome Driver
run: php artisan dusk:chrome-driver
- name: Start Chrome Driver
run: ./vendor/laravel/dusk/bin/chromedriver-linux &
- name: Run Laravel Server
run: php artisan serve &
- name: Run Dusk Tests
run: php artisan dusk