イントロダクションIntroduction
Laravel Duskは、表現力豊かで使いやすいブラウザ自動化およびテストAPIを提供します。デフォルトではDuskを使用するために、ローカルコンピュータへJDKやSeleniumをインストールする必要はありません。代わりに、DuskはスタンドアロンのChromeDriverを使用します。ただし、他のSelenium互換ドライバも自由に利用できます。Laravel Dusk[https://github.com/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 local computer. Instead, Dusk uses a standalone ChromeDriver[https://sites.google.com/chromium.org/driver] installation. However, you are free to utilize any other Selenium compatible driver you wish.
インストールInstallation
使用を開始するには、Google Chromeをインストールして、プロジェクトにLaravel/Dusk
Composer依存パッケージを追加する必要があります。To get started, you should install Google Chrome[https://www.google.com/chrome] and add the laravel/dusk
Composer dependency to your project:
composer require laravel/dusk --dev
[!WARNING]
Warning! 本番環境へDuskをインストールしてはいけません。インストールすると、アプリケーションに対する未認証でのアクセスを許すようになります。
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:install
Artisanコマンドを実行します。dusk:install
コマンドは、tests/Browser
ディレクトリとサンプルのDuskテスト、およびオペレーティングシステムに合わせたChromeドライバのバイナリを作成します。After installing the Dusk package, execute the dusk:install
Artisan command. The dusk:install
command will create a tests/Browser
directory, an example Dusk test, and install the Chrome Driver binary for your operating system:
php artisan dusk:install
次に、アプリケーションの.env
ファイルにAPP_URL
環境変数を設定します。この値は、ブラウザでアプリケーションにアクセスするために使用するURLと一致させる必要があります。Next, set the APP_URL
environment variable in your application's .env
file. This value should match the URL you use to access your application in a browser.
Laravel Sailを使用してローカル開発環境を管理している場合は、Duskテストの設定と実行に関するSailのドキュメントも参照してください。[!NOTE]
Note:
If you are using Laravel Sail[/docs/{{version}}/sail] to manage your local development environment, please also consult the Sail documentation on configuring and running Dusk tests[/docs/{{version}}/sail#laravel-dusk].
Chromeドライバインストールの管理Managing ChromeDriver Installations
dusk:install
コマンドにより、Laravel Duskに含まれるChromeドライバとは別のバージョンをインストールしたい場合は、dusk:chrome-driver
コマンドが使用できます。If you would like to install a different version of ChromeDriver than what is installed by Laravel Dusk via the dusk:install
command, you may use the dusk:chrome-driver
command:
# OSに合った最新バージョンのChromeドライバのインストール
php artisan dusk:chrome-driver
# OSに合った指定バージョンのChromeドライバのインストール
php artisan dusk:chrome-driver 86
# 全てのOSに合ったChromeドライバのインストール
php artisan dusk:chrome-driver --all
# Chrome/Chromiumのバージョンを調べ、OSに合ったChromeドライバのバージョンをインストール
php artisan dusk:chrome-driver --detect
Warning! Dusk実行には、実行可能な
chromedriver
バイナリが必要です。Dusk実行時に問題がある場合は、このバイナリを実行可能に確実にするために、chmod -R 0755 vendor/laravel/dusk/bin
コマンドを実行してみてください。[!WARNING]
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/chromium.org/driver] 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
*/
public static function prepare(): void
{
// 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:
use Facebook\WebDriver\Remote\RemoteWebDriver;
/**
* RemoteWebDriverインスタンスの生成
*/
protected function driver(): RemoteWebDriver
{
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
各テスト終了後のデータベースリセットResetting the Database After Each Test
作成するテストのほとんどは、アプリケーションのデータベースからデータを取得するページを操作します。ただし、DuskテストではRefreshDatabase
トレイトを使用しないでください。RefreshDatabase
トレイトは、HTTPリクエスト間で適用または利用できないデータベーストランザクションを活用します。代わりにDatabaseMigrations
か、DatabaseTruncation
の2トレイトを使用するオプションがあります。Most of the tests you write will interact with pages that retrieve data from your application's database; however, your Dusk tests should never use the RefreshDatabase
trait. The RefreshDatabase
trait leverages database transactions which will not be applicable or available across HTTP requests. Instead, you have two options: the DatabaseMigrations
trait and the DatabaseTruncation
trait.
データベースマイグレーションの利用Using Database Migrations
DatabaseMigrations
トレイトは、各テスト実行前に、データベースのマイグレーションを実行します。しかし、テストごとにデータベースのテーブルを削除し、再作成するのは一般的に、テーブルを切り詰めるよりも遅いでしょう。The DatabaseMigrations
trait will run your database migrations before each test. However, dropping and re-creating your database tables for each test is typically slower than truncating the tables:
<?php
namespace Tests\Browser;
use App\Models\User;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Laravel\Dusk\Chrome;
use Tests\DuskTestCase;
class ExampleTest extends DuskTestCase
{
use DatabaseMigrations;
}
[!WARNING]
Warning! Duskテストの実行時には、SQLiteメモリ内データベースを使用できません。ブラウザは独自のプロセス内で実行されるため、他のプロセスのメモリ内データベースにアクセスすることはできません。
SQLite in-memory databases may not be used when executing Dusk tests. Since the browser executes within its own process, it will not be able to access the in-memory databases of other processes.
データベースの切り捨てUsing Database Truncation
DatabaseTruncation
トレイトを使用する場合は、事前にComposerパッケージマネージャを使用し、doctrine/dbal
パッケージをインストールする必要があります。Before using the DatabaseTruncation
trait, you must install the doctrine/dbal
package using the Composer package manager:
composer require --dev doctrine/dbal
DatabaseTruncation
トレイトは、最初のテストで、データベースのテーブルを確実に作成するため、データベースマイグレーションを実行します。しかし、以降のテストでは、すべてのデータベースマイグレーションを再実行するよりも速度が早いため、データベースのテーブルを単に切り捨てます。The DatabaseTruncation
trait will migrate your database on the first test in order to ensure your database tables have been properly created. However, on subsequent tests, the database's tables will simply be truncated - providing a speed boost over re-running all of your database migrations:
<?php
namespace Tests\Browser;
use App\Models\User;
use Illuminate\Foundation\Testing\DatabaseTruncation;
use Laravel\Dusk\Chrome;
use Tests\DuskTestCase;
class ExampleTest extends DuskTestCase
{
use DatabaseTruncation;
}
デフォルトでこのトレイトは、migrations
を除くすべてのテーブルを切り捨てます。切り捨てるテーブルをカスタマイズしたい場合は、$tablesToTruncate
プロパティをテストクラスで定義してください。By default, this trait will truncate all tables except the migrations
table. If you would like to customize the tables that should be truncated, you may define a $tablesToTruncate
property on your test class:
/**
* 切り捨てるテーブルを指定
*
* @var array
*/
protected $tablesToTruncate = ['users'];
もしくは、テストクラスに$exceptTables
プロパティを定義し、切り捨てから除外するテーブルを指定することもできます。Alternatively, you may define an $exceptTables
property on your test class to specify which tables should be excluded from truncation:
/**
* 切り捨てから除外するテーブルを指定
*
* @var array
*/
protected $exceptTables = ['users'];
テーブルを切り捨てるデータベースの接続を指定するには、テストクラスに $connectionsToTruncate
プロパティを定義してください。To specify the database connections that should have their tables truncated, you may define a $connectionsToTruncate
property on your test class:
/**
* テーブルを切り捨てる接続を指定
*
* @var array
*/
protected $connectionsToTruncate = ['mysql'];
データベースの切り捨ての前後にコードを実行したい場合は、テストクラスにbeforeTruncatingDatabase
、afterTruncatingDatabase
メソッドを定義してください。If you would like to execute code before or after database truncation is performed, you may define beforeTruncatingDatabase
or afterTruncatingDatabase
methods on your test class:
/**
* データベースの切り捨てを始める前に実行する作業
*/
protected function beforeTruncatingDatabase(): void
{
//
}
/**
* データベースの切り捨てを完了後に実行する作業
*/
protected function afterTruncatingDatabase(): void
{
//
}
テストの実行Running Tests
ブラウザのテストを実行するには、dusk
Artisanコマンドを実行します。To run your browser tests, execute 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
dusk
コマンドは、特定のグループのテストのみを実行できるようにするなど、PHPUnitテストランナが通常受け付ける引数を全て受け入れます。The dusk
command accepts any argument that is normally accepted by the PHPUnit test runner, such as allowing you to only run the tests for a given group[https://docs.phpunit.de/en/10.5/annotations.html#group]:
php artisan dusk --group=foo
Laravel Sailを使用してローカル開発環境を管理している場合は、Duskテストの設定と実行に関するSailのドキュメントを参照してください。[!NOTE]
Note:
If you are using Laravel Sail[/docs/{{version}}/sail] to manage your local development environment, please consult the Sail documentation on configuring and running Dusk tests[/docs/{{version}}/sail#laravel-dusk].
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
*/
public static function prepare(): void
{
// static::startChromeDriver();
}
さらに、9515以外のポートでChromeDriverを起動する場合は、同じクラスのdriver
メソッドを変更して正しいポートを反映する必要があります。In addition, if you start ChromeDriver on a port other than 9515, you should modify the driver
method of the same class to reflect the correct port:
use Facebook\WebDriver\Remote\RemoteWebDriver;
/**
* RemoteWebDriverインスタンスの生成
*/
protected function driver(): RemoteWebDriver
{
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.
ブラウザの基本Browser Basics
ブラウザの生成Creating Browsers
開始にあたり、アプリケーションへログインできることを確認するテストを作成してみましょう。テストを生成した後、ログインページに移動し、ログイン情報を入力して、「ログイン」ボタンをクリックするようにテストを変更します。ブラウザインスタンスを作成するには、Duskテスト内からbrowse
メソッドを呼び出します。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, you may call the browse
method from within your Dusk test:
<?php
namespace Tests\Browser;
use App\Models\User;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Laravel\Dusk\Browser;
use Laravel\Dusk\Chrome;
use Tests\DuskTestCase;
class ExampleTest extends DuskTestCase
{
use DatabaseMigrations;
/**
* 基本的なブラウザテスト例
*/
public function test_basic_example(): void
{
$user = User::factory()->create([
'email' => 'taylor@laravel.com',
]);
$this->browse(function (Browser $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 closure. A browser instance will automatically be passed to this closure by Dusk and is the main object used to interact with and make assertions against your application.
複数のブラウザの作成Creating Multiple Browsers
テストを適切に実行するために、複数のブラウザが必要になる場合があります。たとえば、WebSocketと対話するチャット画面をテストするために複数のブラウザが必要になる場合があります。複数のブラウザを作成するには、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, simply add more browser arguments to the signature of the closure given to the browse
method:
$this->browse(function (Browser $first, Browser $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');
});
ナビゲーションNavigation
visit
メソッドを使用して、アプリケーション内の特定のURIに移動できます。The visit
method may be used to navigate to a given URI within your application:
$browser->visit('/login');
visitRoute
メソッドを使用して名前付きルートへ移動できます。You may use the visitRoute
method to navigate to a named route[/docs/{{version}}/routing#named-routes]:
$browser->visitRoute('login');
back
およびforward
メソッドを使用して「戻る」および「進む」をナビゲートできます。You may navigate "back" and "forward" using the back
and forward
methods:
$browser->back();
$browser->forward();
refresh
メソッドを使用してページを更新できます。You may use the refresh
method to refresh the page:
$browser->refresh();
ブラウザウィンドウのリサイズ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 its 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();
スクリーン上の別の位置へブラウザのウィンドウを移動する場合は、move
メソッドを使います。You may use the move
method to move the browser window to a different position on your screen:
$browser->move($x = 100, $y = 100);
ブラウザマクロBrowser Macros
さまざまなテストで再利用可能なカスタムブラウザメソッドを定義したい場合は、Browser
クラスでmacro
メソッドを使用できます。通常、このメソッドはサービスプロバイダのboot
メソッドで呼び出す必要があります。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のブラウザマクロを登録
*/
public function boot(): void
{
Browser::macro('scrollToElement', function (string $element = null) {
$this->script("$('html, body').animate({ scrollTop: $('$element').offset().top }, 0);");
return $this;
});
}
}
macro
関数は、最初の引数に名前を取り、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
instance:
$this->browse(function (Browser $browser) use ($user) {
$browser->visit('/pay')
->scrollToElement('#credit-card-details')
->assertSee('Enter Credit Card Details');
});
認証Authentication
多くの場合、認証が必要なページをテストすると思います。すべてのテスト中にアプリケーションのログイン画面と対話するのを回避するために、DuskのloginAs
メソッドを使用できます。loginAs
メソッドは、認証可能なモデルまたは認証可能なモデルインスタンスに関連付けられた主キーを引数に取ります。Often, you will be testing pages that require authentication. You can use Dusk's loginAs
method in order to avoid interacting with your application's login screen during every test. The loginAs
method accepts a primary key associated with your authenticatable model or an authenticatable model instance:
use App\Models\User;
use Laravel\Dusk\Browser;
$this->browse(function (Browser $browser) {
$browser->loginAs(User::find(1))
->visit('/home');
});
Warning!
loginAs
メソッドを使用した後、ファイル内のすべてのテストでユーザーセッションを維持します。[!WARNING]
After using theloginAs
method, the user session will be maintained for all tests within the file.
クッキーCookies
cookie
メソッドを使用して、暗号化されたCookieの値を取得または設定できます。Laravelによって作成されたすべてのCookieはデフォルトで暗号化されています。You may use the cookie
method to get or set an encrypted cookie's value. By default, all of the cookies created by Laravel are encrypted:
$browser->cookie('name');
$browser->cookie('name', 'Taylor');
暗号化していないクッキーの値を取得/セットするには、plainCookie
メソッドを使います。You may use the plainCookie
method to get or set an unencrypted cookie's value:
$browser->plainCookie('name');
$browser->plainCookie('name', 'Taylor');
指定クッキーを削除するには、deleteCookie
メソッドを使います。You may use the deleteCookie
method to delete the given cookie:
$browser->deleteCookie('name');
JavaScriptの実行Executing JavaScript
script
メソッドを使用して、ブラウザ内で任意のJavaScript文を実行できます。You may use the script
method to execute arbitrary JavaScript statements within the browser:
$browser->script('document.documentElement.scrollTop = 0');
$browser->script([
'document.body.scrollTop = 0',
'document.documentElement.scrollTop = 0',
]);
$output = $browser->script('return window.location.pathname');
スクリーンショットの取得Taking a Screenshot
スクリーンショットを取るには、screenshot
メソッドを使います。指定したファイル名で保存されます。スクリーンショットはすべて、tests/Browser/screenshots
ディレクトリへ保存します。You may use the screenshot
method to take a screenshot and store it with the given filename. All screenshots will be stored within the tests/Browser/screenshots
directory:
$browser->screenshot('filename');
responsiveScreenshots
メソッドは、様々なブレークポイントで一連のスクリーンショットを取得するために使用します。The responsiveScreenshots
method may be used to take a series of screenshots at various breakpoints:
$browser->responsiveScreenshots('filename');
コンソール出力をディスクへ保存Storing Console Output to Disk
storeConsoleLog
メソッドを使用して、現在のブラウザのコンソール出力を指定するファイル名でディスクへ書き込められます。コンソール出力は、tests/Browser/console
ディレクトリへ保存します。You may use the storeConsoleLog
method to write the current browser's console output to disk with the given filename. Console output will be stored within the tests/Browser/console
directory:
$browser->storeConsoleLog('filename');
ページソースをディスクへ保存するStoring Page Source to Disk
storeSource
メソッドを使用して、現在のページソースを指定するファイル名でディスクへ書き込みできます。ページソースはtests/Browser/source
ディレクトリへ保存します。You may use the storeSource
method to write the current page's source to disk with the given filename. The page source will be stored within the tests/Browser/source
directory:
$browser->storeSource('filename');
要素操作Interacting With Elements
DuskセレクタDusk Selectors
要素と対話するための適切なCSSセレクタを選択することは、Duskテストを作成する上で最も難しい部分の1つです。時間の経過とともに、フロントエンドの変更により、次のような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>
// Test…
$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, when interacting with a Dusk browser, prefix the selector with @
to manipulate the attached element within your test:
// HTML…
<button dusk="login-button">Login</button>
// Test…
$browser->click('@login-button');
必要であれば、selectorHtmlAttribute
メソッドを使用し、Duskセレクタで使用するHTML属性をカスタマイズできます。通常、このメソッドは、アプリケーションのAppServiceProvider
のboot
メソッドから呼び出します。If desired, you may customize the HTML attribute that the Dusk selector utilizes via the selectorHtmlAttribute
method. Typically, this method should be called from the boot
method of your application's AppServiceProvider
:
use Laravel\Dusk\Dusk;
Dusk::selectorHtmlAttribute('data-dusk');
テキスト、値、属性Text, Values, and Attributes
値の取得/設定Retrieving and Setting Values
Duskは、ページ上の要素の現在の値、表示テキスト、属性を操作するための方法をいくつか提供します。たとえば、特定のCSSまたはDuskセレクタに一致する要素の「値」を取得するには、value
メソッドを使用します。Dusk provides several methods for interacting with the current value, display text, and attributes of elements on the page. For example, to get the "value" of an element that matches a given CSS or Dusk selector, use the value
method:
// 値の取得
$value = $browser->value('selector');
// 値の設定
$browser->value('selector', 'value');
指定したフィールド名を持つインプット要素の「値」を取得するには、inputValue
メソッドを使ってください。You may use the inputValue
method to get the "value" of an input element that has a given field name:
$value = $browser->inputValue('field');
テキストの取得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 the value of an attribute of an element matching the given selector:
$attribute = $browser->attribute('selector', 'value');
フォーム操作Interacting With 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');
このメソッドは必要に応じて1引数を取りますが、CSSセレクタをtype
メソッドに渡す必要はないことに注意してください。CSSセレクタが提供されていない場合、Duskは指定したname
属性を持つinput
または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
or textarea
field 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');
typeSlowly
メソッドによりDuskへゆっくりとタイプするように指示できます。Duskはデフォルトでキー押下間に100ミリ秒の間隔を開けます。このキー押下間の時間をカスタマイズするには、メソッドの第3引数へ適切なミリ秒数を渡してください。You can instruct Dusk to type slowly using the typeSlowly
method. By default, Dusk will pause for 100 milliseconds between key presses. To customize the amount of time between key presses, you may pass the appropriate number of milliseconds as the third argument to the method:
$browser->typeSlowly('mobile', '+1 (202) 555-5555');
$browser->typeSlowly('mobile', '+1 (202) 555-5555', 300);
テキストをゆっくりと追加するため、appendSlowly
メソッドが使用できます。You may use the appendSlowly
method to append text slowly:
$browser->type('tags', 'foo')
->appendSlowly('tags', ', bar, baz');
ドロップダウンDropdowns
select
要素で使用可能な値を選択するには、select
メソッドを使用できます。type
メソッドと同様に、select
メソッドは完全なCSSセレクタを必要としません。select
メソッドに値を渡すときは、表示テキストの代わりに基になるオプション値を渡す必要があります。To select a value available on a select
element, 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 argument:
$browser->select('size');
select
メソッドの第2引数に配列を指定することで、複数の選択肢を選択するように指定できます。By providing an array as the second argument to the select
method, you can instruct the method to select multiple options:
$browser->select('categories', ['Art', 'Music']);
チェックボックスCheckboxes
チェックボックス入力を「チェック」するには、check
メソッドを使用します。他の多くの入力関連メソッドと同様に、完全なCSSセレクタは必要ありません。CSSセレクタの一致が見つからない場合、Duskは一致するname
属性を持つチェックボックスを検索します。To "check" a checkbox input, you may use the check
method. Like many other input related methods, a full CSS selector is not required. If a CSS selector match can't be found, Dusk will search for a checkbox with a matching name
attribute:
$browser->check('terms');
uncheck
メソッドは、チェックボックス入力を「チェック解除」するために使用します。The uncheck
method may be used to "uncheck" a checkbox input:
$browser->uncheck('terms');
ラジオボタンRadio Buttons
radio
入力オプションを「選択」するには、radio
メソッドを使用します。他の多くの入力関連メソッドと同様に、完全なCSSセレクタは必要ありません。CSSセレクタの一致が見つからない場合、Duskは「name」属性と「value」属性が一致する「radio」入力を検索します。To "select" a radio
input option, you may use the radio
method. Like many other input related methods, a full CSS selector is not required. If a CSS selector match can't be found, Dusk will search for a radio
input with matching name
and value
attributes:
$browser->radio('size', 'large');
ファイルの添付Attaching Files
attach
メソッドは、ファイルをfile
入力要素に添付するために使用します。他の多くの入力関連メソッドと同様に、完全なCSSセレクタは必要ありません。CSSセレクタの一致が見つからない場合、Duskは一致するname
属性を持つfile
入力を検索します。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 a CSS selector match can't be found, Dusk will search for a file
input with a matching name
attribute:
$browser->attach('photo', __DIR__.'/photos/mountains.png');
Warning! 添付機能を使用するには、サーバへ
Zip
PHP拡張機能をインストールし、有効にする必要があります。[!WARNING]
The attach function requires theZip
PHP extension to be installed and enabled on your server.
ボタンの押下Pressing Buttons
press
メソッドを使用して、ページ上のボタン要素をクリックできます。press
メソッドで指定する引数は、ボタンの表示テキストまたはCSS/Duskセレクタのどちらかです。The press
method may be used to click a button element on the page. The argument given to the press
method may be either the display text of the button or a CSS / Dusk selector:
$browser->press('Login');
フォームを送信する場合、多くのアプリケーションは、フォームが押された後にフォームの送信ボタンを無効にし、フォーム送信のHTTPリクエストが完了したときにボタンを再度有効にします。ボタンを押してボタンが再度有効になるのを待つには、pressAndWaitFor
メソッドを使用します。When submitting forms, many applications disable the form's submission button after it is pressed and then re-enable the button when the form submission's HTTP request is complete. To press a button and wait for the button to be re-enabled, you may use the pressAndWaitFor
method:
// ボタンを押して、有効になるまで最大5秒待つ
$browser->pressAndWaitFor('Save');
// ボタンを押して、有効になるまで最大1秒待つ
$browser->pressAndWaitFor('Save', 1);
リンクのクリック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);
seeLink
メソッドを使用して、指定する表示テキストのリンクがページに表示されているかどうかを確認できます。You may use the seeLink
method to determine if a link with the given display text is visible on the page:
if ($browser->seeLink($linkText)) {
// ...
}
[!WARNING]
Warning! これらのメソッドはjQueryを操作します。jQueryがページで利用できない場合、Duskは自動的にそれをページに挿入して、テストの期間中利用できるようにします。
These methods interact 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.
キーボードの使用Using the Keyboard
keys
メソッドを使用すると、type
メソッドで通常できるより複雑な入力シーケンスを特定の要素に提供できます。たとえば、値を入力するときに修飾キーを押したままにするようにDuskに指示できます。以下の例では、指定したセレクタに一致する要素へtaylor
を入力している間、shift
キーが押されます。taylor
の入力後、swift
が修飾キーなしで入力されます。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 instruct Dusk to hold modifier keys while 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, swift
will be typed without any modifier keys:
$browser->keys('selector', ['{shift}', 'taylor'], 'swift');
keys
メソッドのもう1つの有益な使用例は、アプリケーションのプライマリCSSセレクタに「キーボードショートカット」の組み合わせを送信することです。Another valuable use case for the keys
method is sending a "keyboard shortcut" combination to the primary CSS selector for your application:
$browser->keys('.app', ['{command}', 'j']);
Note:
{command}
など、すべての修飾キーは{}
文字でラップし、GitHubで見つかるFacebook\WebDriver\WebDriverKeys
クラスで定義された定数です。[!NOTE]
All modifier keys such as{command}
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].
読み書きしやすいキーボード操作Fluent Keyboard Interactions
DuskはwithKeyboard
メソッドも提供しており、Laravel\Dusk\Keyboard
クラスを使用して複雑なキーボード操作を読み書きしやすく、実行できます。Keyboard
クラスはpress
、release
、type
、pause
メソッドを提供しています。Dusk also provides a withKeyboard
method, allowing you to fluently perform complex keyboard interactions via the Laravel\Dusk\Keyboard
class. The Keyboard
class provides press
, release
, type
, and pause
methods:
use Laravel\Dusk\Keyboard;
$browser->withKeyboard(function (Keyboard $keyboard) {
$keyboard->press('c')
->pause(1000)
->release('c')
->type(['c', 'e', 'o']);
});
キーボードマクロKeyboard Macros
テストスイート全体で簡単に再利用できるカスタムキーボード操作を定義したい場合は、Keyboard
クラスが提供するmacro
メソッドが使えます。通常、このメソッドは、サービスプロバイダのboot
メソッドから呼び出します。If you would like to define custom keyboard interactions that you can easily re-use throughout your test suite, you may use the macro
method provided by the Keyboard
class. Typically, you should call this method from a service provider's[/docs/{{version}}/providers] boot
method:
<?php
namespace App\Providers;
use Facebook\WebDriver\WebDriverKeys;
use Illuminate\Support\ServiceProvider;
use Laravel\Dusk\Keyboard;
use Laravel\Dusk\OperatingSystem;
class DuskServiceProvider extends ServiceProvider
{
/**
* Duskのブラウザマクロの登録
*/
public function boot(): void
{
Keyboard::macro('copy', function (string $element = null) {
$this->type([
OperatingSystem::onMac() ? WebDriverKeys::META : WebDriverKeys::CONTROL, 'c',
]);
return $this;
});
Keyboard::macro('paste', function (string $element = null) {
$this->type([
OperatingSystem::onMac() ? WebDriverKeys::META : WebDriverKeys::CONTROL, 'v',
]);
return $this;
});
}
}
macro
関数は最初の引数に名前、2番目の引数にクロージャを引数に取ります。マクロのクロージャは、Keyboard
インスタンスのメソッドとしてマクロを呼び出すときに実行します。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 Keyboard
instance:
$browser->click('@textarea')
->withKeyboard(fn (Keyboard $keyboard) => $keyboard->copy())
->click('@another-textarea')
->withKeyboard(fn (Keyboard $keyboard) => $keyboard->paste());
マウスの使用Using the Mouse
要素のクリックClicking on Elements
click
メソッドを使用して、指定したCSSまたはDuskセレクタに一致する要素をクリックできます。The click
method may be used to click on an element matching the given CSS or Dusk selector:
$browser->click('.selector');
clickAtXPath
メソッドを使用して、指定したXPath式に一致する要素をクリックできます。The clickAtXPath
method may be used to click on an element matching the given XPath expression:
$browser->clickAtXPath('//div[@class = "selector"]');
clickAtPoint
メソッドを使用して、ブラウザの表示可能領域を基準にした特定の座標ペアで最上位の要素をクリックできます。The clickAtPoint
method may be used to click on the topmost element at a given pair of coordinates relative to the viewable area of the browser:
$browser->clickAtPoint($x = 0, $y = 0);
doubleClick
メソッドを使用して、マウスのダブルクリックをシミュレートできます。The doubleClick
method may be used to simulate the double click of a mouse:
$browser->doubleClick();
$browser->doubleClick('.selector');
rightClick
メソッドを使用して、マウスの右クリックをシミュレートできます。The rightClick
method may be used to simulate the right click of a mouse:
$browser->rightClick();
$browser->rightClick('.selector');
clickAndHold
メソッドを使用して、マウスボタンがクリックされたままにしている状況をシミュレートできます。その後のreleaseMouse
メソッドの呼び出しは、この動作を元に戻し、マウスボタンを離します。The clickAndHold
method may be used to simulate a mouse button being clicked and held down. A subsequent call to the releaseMouse
method will undo this behavior and release the mouse button:
$browser->clickAndHold('.selector');
$browser->clickAndHold()
->pause(1000)
->releaseMouse();
controlClick
メソッドは、ブラウザのctrl+click
イベントをシミュレートするために使います。The controlClick
method may be used to simulate the ctrl+click
event within the browser:
$browser->controlClick();
$browser->controlClick('.selector');
マウスオーバMouseover
mouseover
メソッドは、指定したCSSまたはDuskセレクタに一致する要素の上にマウスを移動する必要がある場合に使用します。The mouseover
method may be used when you need to move the mouse over an element matching the given CSS or Dusk selector:
$browser->mouseover('.selector');
ドラッグ・アンド・ドロップDrag and 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', $pixels = 10);
$browser->dragRight('.selector', $pixels = 10);
$browser->dragUp('.selector', $pixels = 10);
$browser->dragDown('.selector', $pixels = 10);
最後に、指定したオフセットで要素をドラッグできます。Finally, you may drag an element by a given offset:
$browser->dragOffset('.selector', $x = 10, $y = 10);
JavaScriptダイアログJavaScript Dialogs
Duskは、JavaScriptダイアログを操作するためにさまざまなメソッドを提供しています。たとえば、waitForDialog
メソッドを使用して、JavaScriptダイアログが表示されるまで待機できます。このメソッドは、ダイアログが表示されるまで何秒待つかを示すオプションの引数を受け入れます。Dusk provides various methods to interact with JavaScript Dialogs. For example, you may use the waitForDialog
method to wait for a JavaScript dialog to appear. This method accepts an optional argument indicating how many seconds to wait for the dialog to appear:
$browser->waitForDialog($seconds = null);
assertDialogOpened
メソッドを使用して、ダイアログが表示され、指定するメッセージが含まれていることを宣言できます。The assertDialogOpened
method may be used to assert that a dialog has been displayed and contains the given message:
$browser->assertDialogOpened('Dialog message');
JavaScriptダイアログにプロンプトが含まれている場合は、typeInDialog
メソッドを使用してプロンプトに値を入力できます。If the JavaScript dialog contains a prompt, you may use the typeInDialog
method to type a value into the prompt:
$browser->typeInDialog('Hello World');
"OK"ボタンをクリックして開いているJavaScriptダイアログを閉じるには、acceptDialog
メソッドを呼び出します。To close an open JavaScript dialog by clicking the "OK" button, you may invoke the acceptDialog
method:
$browser->acceptDialog();
[キャンセル]ボタンをクリックして開いているJavaScriptダイアログを閉じるには、dismissDialog
メソッドを呼び出します。To close an open JavaScript dialog by clicking the "Cancel" button, you may invoke the dismissDialog
method:
$browser->dismissDialog();
インラインフレーム操作Interacting With Inline Frames
iframe内の要素をやり取りする必要がある場合は、withinFrame
メソッドを使用する必要があります。withinFrame
メソッドへ渡たすクロージャ内で行う全ての要素の操作は、指定したiframeのコンテキストにスコープされます。If you need to interact with elements within an iframe, you may use the withinFrame
method. All element interactions that take place within the closure provided to the withinFrame
method will be scoped to the context of the specified iframe:
$browser->withinFrame('#credit-card-details', function ($browser) {
$browser->type('input[name="cardnumber"]', '4242424242424242')
->type('input[name="exp-date"]', '12/24')
->type('input[name="cvc"]', '123');
})->press('Pay');
});
セレクタの範囲指定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 closure given to the with
method will be scoped to the original selector:
$browser->with('.table', function (Browser $table) {
$table->assertSee('Hello World')
->clickLink('Delete');
});
現在のスコープ外でアサートを実行する必要がある場合があります。これを実現するには、elsewhere
メソッドを使用できます。You may occasionally need to execute assertions outside of the current scope. You may use the elsewhere
and elsewhereWhenAvailable
methods to accomplish this:
$browser->with('.table', function (Browser $table) {
// 現在のスコープは`body .table`
$browser->elsewhere('.page-title', function (Browser $title) {
// 現在のスコープは`body .page-title`
$title->assertSee('Hello World');
});
$browser->elsewhereWhenAvailable('.page-title', function (Browser $title) {
// 現在のスコープは`body .page-title`
$title->assertSee('Hello World');
});
});
要素の待機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 become visible on the page or even wait until a given JavaScript expression evaluates to true
.
待機Waiting
指定するミリ秒数だけテストを一時停止する必要がある場合は、pause
メソッドを使用します。If you just need to pause the test for a given number of milliseconds, use the pause
method:
$browser->pause(1000);
もし、指定した条件がtrue
のときだけテストを一時停止したい場合は、pauseIf
メソッドを使用してください。If you need to pause the test only if a given condition is true
, use the pauseIf
method:
$browser->pauseIf(App::environment('production'), 1000);
同様に、指定した条件がtrue
でないときにテストを一時停止する必要がある場合は、pauseUnless
メソッドを使用します。Likewise, if you need to pause the test unless a given condition is true
, you may use the pauseUnless
method:
$browser->pauseUnless(App::environment('testing'), 1000);
セレクタの待機Waiting for Selectors
waitFor
メソッドを使用して、指定するCSSまたはDuskセレクタに一致する要素がページに表示されるまでテストの実行を一時停止できます。デフォルトでは、これは例外をスローする前に最大5秒間テストを一時停止します。必要に応じて、メソッドの2番目の引数にカスタムタイムアウトしきい値を渡せます。The waitFor
method may be used to pause the execution of the test until the element matching the given CSS or Dusk 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 element matching the given selector contains the given text:
// セレクタが指定テキストを持つまで、最長5秒待つ
$browser->waitForTextIn('.selector', 'Hello World');
// セレクタが指定テキストを持つまで、最長5秒待つ
$browser->waitForTextIn('.selector', 'Hello World', 1);
指定するセレクタに一致する要素がページから無くなるまで待つこともできます。You may also wait until the element matching the given selector is missing from the page:
// セレクタが消えるまで、最長5秒待つ
$browser->waitUntilMissing('.selector');
// セレクタが消えるまで、最長1秒待つ
$browser->waitUntilMissing('.selector', 1);
あるいは、与えられたセレクタにマッチする要素が有効または無効になるまで待つこともできます。Or, you may wait until the element matching the given selector is enabled or disabled:
// セレクタが有効になるまで最大5秒待つ
$browser->waitUntilEnabled('.selector');
// セレクタが有効になるまで最大1秒待つ
$browser->waitUntilEnabled('.selector', 1);
// セレクタが無効になるまで最大5秒待つ
$browser->waitUntilDisabled('.selector');
// セレクタが無効になるまで最大1秒待つ
$browser->waitUntilDisabled('.selector', 1);
利用可能時限定のセレクタScoping Selectors When Available
場合によっては、特定のセレクタに一致する要素が表示されるのを待ってから、その要素と対話したいことがあります。たとえば、モーダルウィンドウが使用可能になるまで待ってから、モーダル内の"OK"ボタンを押すことができます。これを実現するには、whenAvailable
メソッドを使用します。指定するクロージャ内で実行されるすべての要素操作は、元のセレクタにスコープされます。Occasionally, you may wish to wait for an element to appear that matches a given selector and then interact with the element. 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 to accomplish this. All element operations performed within the given closure will be scoped to the original selector:
$browser->whenAvailable('.modal', function (Browser $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 for Inputs
waitForInput
メソッドは、指定した入力フィールドがページ上に表示されるまで、待つために使用します。The waitForInput
method may be used to wait until the given input field is visible on the page:
// 最大5秒間、入力を待つ
$browser->waitForInput($field);
// 最大1秒間、入力を待つ
$browser->waitForInput($field, 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');
waitForLocation
メソッドは、現在のウィンドウの場所が完全修飾URLになるまで待機するためにも使用できます。The waitForLocation
method can also be used to wait for the current window location to be a fully qualified URL:
$browser->waitForLocation('https://example.com/path');
名前付きルートのロケーションを待機することも可能です。You may also wait for a named route's[/docs/{{version}}/routing#named-routes] location:
$browser->waitForRoute($routeName, $parameters);
ページリロードの待機Waiting for Page Reloads
アクションを実行した後に、ページの再読み込みを待つ必要がある場合は、waitForReload
メソッドを使用します。If you need to wait for a page to reload after performing an action, use the waitForReload
method:
use Laravel\Dusk\Browser;
$browser->waitForReload(function (Browser $browser) {
$browser->press('Submit');
})
->assertSee('Success!');
ページのリロードを待つ必要性は、通常、ボタンをクリックした後に発生するため、便利なclickAndWaitForReload
メソッドを使用するとよいでしょう。Since the need to wait for the page to reload typically occurs after clicking a button, you may use the clickAndWaitForReload
method for convenience:
$browser->clickAndWaitForReload('.selector')
->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.data.servers.length > 0');
// 式がtrueになるまで最大1秒間待つ
$browser->waitUntil('App.data.servers.length > 0', 1);
Vue式の待機Waiting on Vue Expressions
waitUntilVue
メソッドとwaitUntilVueIsNot
メソッドを使用して、Vueコンポーネント属性が指定した値になるまで待機できます。The waitUntilVue
and waitUntilVueIsNot
methods may be used to wait until a Vue component[https://vuejs.org] attribute has a given value:
// コンポーネント属性に指定した値が含まれるまで待つ
$browser->waitUntilVue('user.name', 'Taylor', '@user');
// コンポーネント属性に指定した値が含まれなくなるまで待つ
$browser->waitUntilVueIsNot('user.name', null, '@user');
JavaScriptイベントの待機Waiting for JavaScript Events
waitForEvent
メソッドは、JavaScriptイベントが発生するまで、テストの実行を一時停止するために使用します。The waitForEvent
method can be used to pause the execution of a test until a JavaScript event occurs:
$browser->waitForEvent('load');
イベントリスナは現在のスコープにアタッチされ、デフォルトでは body
要素となります。スコープセレクタを使用した場合、イベントリスナは一致する要素にアタッチされます。The event listener is attached to the current scope, which is the body
element by default. When using a scoped selector, the event listener will be attached to the matching element:
$browser->with('iframe', function (Browser $iframe) {
// iframeのロードイベントを待つ
$iframe->waitForEvent('load');
});
もしくは、waitForEvent
メソッドの第2引数へセレクタを指定し、イベントリスナを特定の要素にアタッチすることもできます。You may also provide a selector as the second argument to the waitForEvent
method to attach the event listener to a specific element:
$browser->waitForEvent('load', '.selector');
さらに、document
とwindow
オブジェクトのイベントも待てます。You may also wait for events on the document
and window
objects:
// documentがスクロールされるまで待つ
$browser->waitForEvent('scroll', 'document');
// windowがリサイズされるまで、最大秒数待つ
$browser->waitForEvent('resize', 'window', 5);
コールバックによる待機Waiting With a Callback
Duskの"wait"メソッドの多くは、基盤となる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 closure 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.");
要素をスクロールしてビューに表示Scrolling an Element Into View
要素がブラウザの表示可能領域の外にあるために、要素をクリックできない場合があります。scrollIntoView
メソッドは、指定したセレクタの要素がビュー内に入るまでブラウザウィンドウをスクロールします。Sometimes you may not be able to click on an element because it is outside of the viewable area of the browser. The scrollIntoView
method will scroll the browser window until the element at the given selector is within the view:
$browser->scrollIntoView('.selector')
->click('.selector');
使用可能なアサート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:
assertTitle assertTitleContains assertUrlIs assertSchemeIs assertSchemeIsNot assertHostIs assertHostIsNot assertPortIs assertPortIsNot assertPathBeginsWith assertPathIs assertPathIsNot assertRouteIs assertQueryStringHas assertQueryStringMissing assertFragmentIs assertFragmentBeginsWith assertFragmentIsNot assertHasCookie assertHasPlainCookie assertCookieMissing assertPlainCookieMissing assertCookieValue assertPlainCookieValue assertSee assertDontSee assertSeeIn assertDontSeeIn assertSeeAnythingIn assertSeeNothingIn assertScript assertSourceHas assertSourceMissing assertSeeLink assertDontSeeLink assertInputValue assertInputValueIsNot assertChecked assertNotChecked assertIndeterminate assertRadioSelected assertRadioNotSelected assertSelected assertNotSelected assertSelectHasOptions assertSelectMissingOptions assertSelectHasOption assertSelectMissingOption assertValue assertValueIsNot assertAttribute assertAttributeContains assertAttributeDoesntContain assertAriaAttribute assertDataAttribute assertVisible assertPresent assertNotPresent assertMissing assertInputPresent assertInputMissing assertDialogOpened assertEnabled assertDisabled assertButtonEnabled assertButtonDisabled assertFocused assertNotFocused assertAuthenticated assertGuest assertAuthenticatedAs assertVue assertVueIsNot assertVueContains assertVueDoesntContain
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('/home');
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[/docs/{{version}}/routing#named-routes] 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
URLの現在のハッシュフラグメントが指定するフラグメントと一致することを宣言します。Assert that the URL's current hash fragment matches the given fragment:
$browser->assertFragmentIs('anchor');
assertFragmentBeginsWithassertFragmentBeginsWith
URLの現在のハッシュフラグメントが指定するフラグメントで始まることを宣言します。Assert that the URL's current hash fragment begins with the given fragment:
$browser->assertFragmentBeginsWith('anchor');
assertFragmentIsNotassertFragmentIsNot
URLの現在のハッシュフラグメントが指定するフラグメントと一致しないことを宣言します。Assert that the URL's current hash fragment does not match the given fragment:
$browser->assertFragmentIsNot('anchor');
assertHasCookieassertHasCookie
指定した暗号化クッキーが存在することを宣言します。Assert that the given encrypted cookie is present:
$browser->assertHasCookie($name);
assertHasPlainCookieassertHasPlainCookie
指定した暗号化していないクッキーが存在していることを宣言します。Assert that the given unencrypted cookie is present:
$browser->assertHasPlainCookie($name);
assertCookieMissingassertCookieMissing
指定した暗号化クッキーが存在していないことを宣言します。Assert that the given encrypted cookie is not present:
$browser->assertCookieMissing($name);
assertPlainCookieMissingassertPlainCookieMissing
指定した暗号化していないクッキーが存在していないことを宣言します。Assert that the given unencrypted cookie is not present:
$browser->assertPlainCookieMissing($name);
assertCookieValueassertCookieValue
指定した暗号化クッキーが、指定値を持っていることを宣言します。Assert that an encrypted 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);
assertSeeAnythingInassertSeeAnythingIn
セレクタ内にテキストが存在することを宣言します。Assert that any text is present within the selector:
$browser->assertSeeAnythingIn($selector);
assertSeeNothingInassertSeeNothingIn
セレクタ内にテキストが存在しないことを宣言します。Assert that no text is present within the selector:
$browser->assertSeeNothingIn($selector);
assertScriptassertScript
指定するJavaScript式の評価結果が指定値であることを宣言します。Assert that the given JavaScript expression evaluates to the given value:
$browser->assertScript('window.isLoaded')
->assertScript('document.readyState', 'complete');
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);
aspublic function selectDate(Browser $browser,sertDontSeeLinkassertDontSeeLink
指定したリンクが、ページ上に存在していないことを宣言します。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);
assertIndeterminateassertIndeterminate
指定したチェックボックスが、不定状態であることを宣言します。Assert that the given checkbox is in an indeterminate state:
$browser->assertIndeterminate($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);
assertSelectMissingOptionassertSelectMissingOption
指定値が選択できないことを宣言します。Assert that the given value is not available to be selected:
$browser->assertSelectMissingOption($field, $value);
assertValueassertValue
指定セレクタに一致する要素が、指定値であることを宣言します。Assert that the element matching the given selector has the given value:
$browser->assertValue($selector, $value);
assertValueIsNotassertValueIsNot
指定セレクタに一致する要素が、指定値を持たないことを宣言します。Assert that the element matching the given selector does not have the given value:
$browser->assertValueIsNot($selector, $value);
assertAttributeassertAttribute
指定セレクタに一致する要素が、指定属性に指定値を持っていることを宣言します。Assert that the element matching the given selector has the given value in the provided attribute:
$browser->assertAttribute($selector, $attribute, $value);
assertAttributeContainsassertAttributeContains
指定セレクタに一致する要素が、与えた属性の中に、指定値を持っていることを宣言します。Assert that the element matching the given selector contains the given value in the provided attribute:
$browser->assertAttributeContains($selector, $attribute, $value);
assertAttributeDoesntContainassertAttributeDoesntContain
指定したセレクタに一致する要素が、指定属性に指定値を含まないことを宣言します。Assert that the element matching the given selector does not contain the given value in the provided attribute:
$browser->assertAttributeDoesntContain($selector, $attribute, $value);
assertAriaAttributeassertAriaAttribute
指定セレクタに一致する要素が、指定aria属性に、指定値を持っていることを宣言します。Assert that the element matching the given selector has the given value in the provided aria attribute:
$browser->assertAriaAttribute($selector, $attribute, $value);
たとえば、指定するマークアップが<button aria-label="Add"></button>
であり、aria-label
に対して宣言する場合は、次のようになります。For example, given the markup <button aria-label="Add"></button>
, you may assert against the aria-label
attribute like so:
$browser->assertAriaAttribute('button', 'label', 'Add')
assertDataAttributeassertDataAttribute
指定セレクタに一致する要素が、指定データ属性に指定値を持っていることを宣言します。Assert that the element matching the given selector has the given value in the provided data attribute:
$browser->assertDataAttribute($selector, $attribute, $value);
たとえば、指定するマークアップが<tr id="row-1" data-content="attendees"></tr>
であり、data-label
属性に対して宣言をする場合、次のようになります。For example, given the markup <tr id="row-1" data-content="attendees"></tr>
, you may assert against the data-label
attribute like so:
$browser->assertDataAttribute('#row-1', 'content', 'attendees')
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 in the source:
$browser->assertPresent($selector);
assertNotPresentassertNotPresent
指定セレクタに一致する要素が、ソースに存在しないことを宣言します。Assert that the element matching the given selector is not present in the source:
$browser->assertNotPresent($selector);
assertMissingassertMissing
指定セレクタに一致する要素が、ビジブルでないことを宣言します。Assert that the element matching the given selector is not visible:
$browser->assertMissing($selector);
assertInputPresentassertInputPresent
指定する名前の入力が存在することを宣言します。Assert that an input with the given name is present:
$browser->assertInputPresent($name);
assertInputMissingassertInputMissing
指定する名前の入力がソースに存在しないことを宣言します。Assert that an input with the given name is not present in the source:
$browser->assertInputMissing($name);
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);
assertAuthenticatedassertAuthenticated
そのユーザーが認証済みであることを宣言します。Assert that the user is authenticated:
$browser->assertAuthenticated();
assertGuestassertGuest
そのユーザーが認証されていないことを宣言します。Assert that the user is not authenticated:
$browser->assertGuest();
assertAuthenticatedAsassertAuthenticatedAs
そのユーザーが指定したユーザーとして認証されていることを宣言します。Assert that the user is authenticated as the given user:
$browser->assertAuthenticatedAs($user);
assertVueassertVue
Duskでは、Vueコンポーネントデータの状態についてアサーションを作成することもできます。たとえば、アプリケーションに次のVueコンポーネントが含まれているとします。Dusk even allows you to make assertions on the state of Vue component[https://vuejs.org] 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テストの例
*/
public function test_vue(): void
{
$this->browse(function (Browser $browser) {
$browser->visit('/')
->assertVue('user.name', 'Taylor', '@profile-component');
});
}
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);
assertVueDoesntContainassertVueDoesntContain
指定したVueコンポーネントのデータプロパティが配列で、指定値を含まないことを宣言します。Assert that a given Vue component data property is an array and does not contain the given value:
$browser->assertVueDoesntContain($property, $value, $componentSelector = null);
ページPages
テストでは、いくつかの複雑なアクションを順番に実行する必要がある場合があります。これにより、テストが読みにくくなり、理解しにくくなる可能性があります。Duskページでは、一つのメソッドにより指定ページで実行できる表現力豊かなアクションを定義できます。ページを使用すると、アプリケーションまたは単一ページの一般的なセレクタへのショートカットを定義することもできます。Sometimes, tests require several complicated actions to be performed in sequence. This can make your tests harder to read and understand. Dusk Pages allow you to define expressive actions that may then be performed on a given page via a single method. Pages also allow you to define short-cuts to common selectors for your application or for a single page.
ページの生成Generating Pages
ページオブジェクトを生成するには、dusk:page
Artisanコマンドを実行します。すべてのページオブジェクトは、アプリケーションのtests/Browser/Pages
ディレクトリに配置されます。To generate a page object, execute the dusk:page
Artisan command. All page objects will be placed in your application's 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取得
*/
public function url(): string
{
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. It is not actually necessary to place anything within this method; however, you are free to make these assertions if you wish. These assertions will be run automatically when navigating to the page:
/**
* ブラウザがページ上にあることを宣言
*/
public function assert(Browser $browser): void
{
$browser->assertPathIs($this->url());
}
ページへのナビゲーションNavigating to Pages
ページが定義できたら、visit
メソッドを使用してそのページに移動します。Once a page has been defined, 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 within page classes 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<string, string>
*/
public function elements(): array
{
return [
'@email' => 'input[name=email]',
];
}
ショートカットを定義したら、通常は完全なCSSセレクタを使用する場所であればどこでもショートカットセレクタを使用できます。Once the shortcut has been defined, you may use the shorthand selector anywhere you would typically 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<string, string>
*/
public static function siteElements(): array
{
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
{
// 他のページメソッドの定義…
/**
* 新しいプレイリストの作成
*/
public function createPlaylist(Browser $browser, string $name): void
{
$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 as the first argument to custom page methods:
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, execute 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
{
/**
* コンポーネントのルートセレクタ取得
*/
public function selector(): string
{
return '.date-picker';
}
/**
* ブラウザページにそのコンポーネントが含まれていることを宣言
*/
public function assert(Browser $browser): void
{
$browser->assertVisible($this->selector());
}
/**
* コンポーネントの要素のショートカットを取得
*
* @return array<string, string>
*/
public function elements(): array
{
return [
'@date-field' => 'input.datepicker-input',
'@year-list' => 'div > div.datepicker-years',
'@month-list' => 'div > div.datepicker-months',
'@day-list' => 'div > div.datepicker-days',
];
}
/**
* 指定日付のセレクト
*/
public function selectDate(Browser $browser, int $year, int $month, int $day): void
{
$browser->click('@date-field')
->within('@year-list', function (Browser $browser) use ($year) {
$browser->click($year);
})
->within('@month-list', function (Browser $browser) use ($month) {
$browser->click($month);
})
->within('@day-list', function (Browser $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
{
/**
* 基本的なコンポーネントテスト例
*/
public function test_basic_example(): void
{
$this->browse(function (Browser $browser) {
$browser->visit('/')
->within(new DatePicker, function (Browser $browser) {
$browser->selectDate(2019, 1, 30);
})
->assertSee('January');
});
}
}
継続的インテグレーションContinuous Integration
Warning! ほとんどのDusk継続的インテグレーション設定では、Laravelアプリケーションがポート8000の組み込みPHP開発サーバを使用して提供されることを想定しています。したがって、続行する前に、継続的インテグレーション環境の
APP_URL
環境変数値を確実にhttp://127.0.0.1:8000
に指定してください。[!WARNING]
Most Dusk continuous integration configurations expect your Laravel application to be served using the built-in PHP development server on port 8000. Therefore, before continuing, you should ensure that your continuous integration environment has anAPP_URL
environment variable value ofhttp://127.0.0.1:8000
.
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 --no-reload > /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
- 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 --no-reload &
script:
- php artisan dusk
GitHubアクションGitHub Actions
GitHub Actionsを使用してDuskテストを実行する場合は、次の設定ファイルを開始点として使用できます。TravisCIと同様に、php artisan serve
コマンドを使用してPHPの組み込みWebサーバを起動します。If you are using GitHub Actions[https://github.com/features/actions] to run your Dusk tests, you may use the following 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
env:
APP_URL: "http://127.0.0.1:8000"
DB_USERNAME: root
DB_PASSWORD: root
MAIL_MAILER: log
steps:
- uses: actions/checkout@v4
- name: Prepare The Environment
run: cp .env.example .env
- name: Create Database
run: |
sudo systemctl start mysql
mysql --user="root" --password="root" -e "CREATE DATABASE \ character set UTF8mb4 collate utf8mb4_bin;"
- name: Install Composer Dependencies
run: composer install --no-progress --prefer-dist --optimize-autoloader
- name: Generate Application Key
run: php artisan key:generate
- name: Upgrade Chrome Driver
run: php artisan dusk:chrome-driver --detect
- name: Start Chrome Driver
run: ./vendor/laravel/dusk/bin/chromedriver-linux &
- name: Run Laravel Server
run: php artisan serve --no-reload &
- name: Run Dusk Tests
run: php artisan dusk
- name: Upload Screenshots
if: failure()
uses: actions/upload-artifact@v2
with:
name: screenshots
path: tests/Browser/screenshots
- name: Upload Console Logs
if: failure()
uses: actions/upload-artifact@v2
with:
name: console
path: tests/Browser/console
Chipper CIChipper CI
Chipper CIを使ってDuskテストを実行する場合、以下の設定ファイルを参考にしてください。PHP組み込みサーバを使ってLaravelを実行し、リクエストをリッスンします:If you are using Chipper CI[https://chipperci.com] to run your Dusk tests, you may use the following configuration file as a starting point. We will use PHP's built-in server to run Laravel so we can listen for requests:
# .chipperci.ymlファイル
version: 1
environment:
php: 8.2
node: 16
# Chromeはビルド環境に含まれる
services:
- dusk
# 全コミットをビルド
on:
push:
branches: .*
pipeline:
- name: Setup
cmd: |
cp -v .env.example .env
composer install --no-interaction --prefer-dist --optimize-autoloader
php artisan key:generate
# Create a dusk env file, ensuring APP_URL uses BUILD_HOST
cp -v .env .env.dusk.ci
sed -i "s@APP_URL=.*@APP_URL=http://$BUILD_HOST:8000@g" .env.dusk.ci
- name: Compile Assets
cmd: |
npm ci --no-audit
npm run build
- name: Browser Tests
cmd: |
php -S [::0]:8000 -t public 2>server.log &
sleep 2
php artisan dusk:chrome-driver $CHROME_DRIVER
php artisan dusk --env=ci
データベースの使い方など、Chipper CIでDuskテストを実行する詳細は、Chipper CI公式ドキュメントを参照してください。To learn more about running Dusk tests on Chipper CI, including how to use databases, consult the official Chipper CI documentation[https://chipperci.com/docs/testing/laravel-dusk-new/].