Readouble

Laravel 11.x Laravel Dusk

イントロダクション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をインストールしてはいけません。インストールすると、アプリケーションに対する未認証でのアクセスを許すようになります。[!WARNING]
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.

lightbulb Note: Laravel Sailを使用してローカル開発環境を管理している場合は、Duskテストの設定と実行に関するSailのドキュメントも参照してください。[!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 Warning! Dusk実行には、実行可能なchromedriverバイナリが必要です。Dusk実行時に問題がある場合は、このバイナリを実行可能に確実にするために、chmod -R 0755 vendor/laravel/dusk/binコマンドを実行してみてください。[!WARNING]
Dusk requires the chromedriver 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:

Pest
<?php

use Illuminate\Foundation\Testing\DatabaseMigrations;
use Laravel\Dusk\Browser;

uses(DatabaseMigrations::class);

//
PHPUnit
<?php

namespace Tests\Browser;

use Illuminate\Foundation\Testing\DatabaseMigrations;
use Laravel\Dusk\Browser;
use Tests\DuskTestCase;

class ExampleTest extends DuskTestCase
{
    use DatabaseMigrations;

    //
}

warning Warning! Duskテストの実行時には、SQLiteメモリ内データベースを使用できません。ブラウザは独自のプロセス内で実行されるため、他のプロセスのメモリ内データベースにアクセスすることはできません。[!WARNING]
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トレイトは、最初のテストで、データベースのテーブルを確実に作成するため、データベースマイグレーションを実行します。しかし、以降のテストでは、すべてのデータベースマイグレーションを再実行するよりも速度が早いため、データベースのテーブルを単に切り捨てます。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:

Pest
<?php

use Illuminate\Foundation\Testing\DatabaseTruncation;
use Laravel\Dusk\Browser;

uses(DatabaseTruncation::class);

//
PHPUnit
<?php

namespace Tests\Browser;

use App\Models\User;
use Illuminate\Foundation\Testing\DatabaseTruncation;
use Laravel\Dusk\Browser;
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:

lightbulb Note: Pestを使用する場合は、ベースのDuskTestCaseクラス、もしくはテストファイルを拡張した全クラスで、プロパティやメソッドを定義する必要があります。[!NOTE]
If you are using Pest, you should define properties or methods on the base DuskTestCase class or on any class your test file extends.

/**
 * 切り捨てるテーブルを指定
 *
 * @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'];

データベースの切り捨ての前後にコードを実行したい場合は、テストクラスにbeforeTruncatingDatabaseafterTruncatingDatabaseメソッドを定義してください。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コマンドは、Pest/PHPUnitテストランナーが通常受け付ける任意の引数を受け付けます。たとえば、指定するグループのテストだけを実行したい場合などに使用します。The dusk command accepts any argument that is normally accepted by the Pest / 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

lightbulb Note: Laravel Sailを使用してローカル開発環境を管理している場合は、Duskテストの設定と実行に関するSailのドキュメントを参照してください。[!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:

Pest
<?php

use App\Models\User;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Laravel\Dusk\Browser;

uses(DatabaseMigrations::class);

test('basic example', function () {
    $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');
    });
});
PHPUnit
<?php

namespace Tests\Browser;

use App\Models\User;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Laravel\Dusk\Browser;
use Tests\DuskTestCase;

class ExampleTest extends DuskTestCase
{
    use DatabaseMigrations;

    /**
     * A basic browser test example.
     */
    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($routeName, $parameters);

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 Warning! loginAsメソッドを使用した後、ファイル内のすべてのテストでユーザーセッションを維持します。[!WARNING]
After using the loginAs 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');

screenshotElementは、ページ上の特定の要素のスクリーンショットを撮ります。The screenshotElement method may be used to take a screenshot of a specific element on the page:

$browser->screenshotElement('#selector', '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属性をカスタマイズできます。通常、このメソッドは、アプリケーションのAppServiceProviderbootメソッドから呼び出します。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 Warning! 添付機能を使用するには、サーバへZip PHP拡張機能をインストールし、有効にする必要があります。[!WARNING]
The attach function requires the Zip 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は自動的にそれをページに挿入して、テストの期間中利用できるようにします。[!WARNING]
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']);

lightbulb Note: {command}など、すべての修飾キーは{}文字でラップし、GitHubで見つかるFacebook\WebDriver\WebDriverKeysクラスで定義された定数です。[!NOTE]
All modifier keys such as {command} are wrapped in {} characters, and match the constants defined in the Facebook\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クラスはpressreleasetypepauseメソッドを提供しています。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();

The controlClick method may be used to simulate the ctrl+click event within the browser: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"]', '1224')
        ->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');

さらに、documentwindowオブジェクトのイベントも待てます。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:

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');

assertPathEndsWithassertPathEndsWith

現在のURLパスが指定したパスで終わることを宣言します。Assert that the current URL path ends with the given path:

$browser->assertPathEndsWith('/home');

assertPathContainsassertPathContains

現在のURLパスが指定したパスを含んでいることを宣言します。Assert that the current URL path contains the given path:

$browser->assertPathContains('/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:

Pest
test('vue', function () {
    $this->browse(function (Browser $browser) {
        $browser->visit('/')
                ->assertVue('user.name', 'Taylor', '@profile-component');
    });
});
PHPUnit
/**
 * 基本的な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

デフォルトでページには、urlassertelementsの3メソッドが用意されています。urlassertメソッドは、この後説明します。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;
use Laravel\Dusk\Page;

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:

Pest
<?php

use Illuminate\Foundation\Testing\DatabaseMigrations;
use Laravel\Dusk\Browser;
use Tests\Browser\Components\DatePicker;

uses(DatabaseMigrations::class);

test('basic example', function () {
    $this->browse(function (Browser $browser) {
        $browser->visit('/')
                ->within(new DatePicker, function (Browser $browser) {
                    $browser->selectDate(2019, 1, 30);
                })
                ->assertSee('January');
    });
});
PHPUnit
<?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 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 an APP_URL environment variable value of http://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-chrome-for-testing" }
      ],
      "scripts": {
        "test-setup": "cp .env.testing .env",
        "test": "nohup bash -c './vendor/laravel/dusk/bin/chromedriver-linux --port=9515 > /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:
  - 8.2

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 --port=9515 &
      - 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@v4
        with:
          name: screenshots
          path: tests/Browser/screenshots
      - name: Upload Console Logs
        if: failure()
        uses: actions/upload-artifact@v4
        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/].

章選択

設定

明暗テーマ
light_mode
dark_mode
brightness_auto システム設定に合わせる
テーマ選択
photo_size_select_actual デフォルト
photo_size_select_actual モノクローム(白黒)
photo_size_select_actual Solarized風
photo_size_select_actual GitHub風(青ベース)
photo_size_select_actual Viva(黄緑ベース)
photo_size_select_actual Happy(紫ベース)
photo_size_select_actual Mint(緑ベース)
コードハイライトテーマ選択

明暗テーマごとに、コードハイライトのテーマを指定できます。

テーマ配色確認
スクリーン表示幅
640px
80%
90%
100%

768px以上の幅があるときのドキュメント部分表示幅です。

インデント
無し
1rem
2rem
3rem
原文確認
原文を全行表示
原文を一行ずつ表示
使用しない

※ 段落末のEボタンへカーソルオンで原文をPopupします。

Diff表示形式
色分けのみで区別
行頭の±で区別
削除線と追記で区別

※ [tl!…]形式の挿入削除行の表示形式です。

テストコード表示
両コード表示
Pestのみ表示
PHPUnitのみ表示
OS表示
全OS表示
macOSのみ表示
windowsのみ表示
linuxのみ表示
和文変換

対象文字列と置換文字列を半角スペースで区切ってください。(最大5組各10文字まで)

本文フォント

総称名以外はCSSと同様に、"〜"でエスケープしてください。

コードフォント

総称名以外はCSSと同様に、"〜"でエスケープしてください。

保存内容リセット

localStrageに保存してある設定項目をすべて削除し、デフォルト状態へ戻します。

ヘッダー項目移動

キーボード操作