> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# 瀏覽器測試（Dusk）

> 如何使用 Laravel Dusk，透過 ChromeDriver 執行瀏覽器端對端測試

## Laravel Dusk 是什麼

Laravel Dusk 是能實際操作瀏覽器並驗證整個畫面的 E2E 測試工具。
預設無須另外準備 Selenium 伺服器，可用 ChromeDriver 執行測試。

<Warning>
  官方文件建議新專案改用 Pest 4 的瀏覽器測試。若你已有專案在使用 Dusk 或想使用 Dusk 的 API，可參考本頁。
</Warning>

## 安裝

先安裝 Google Chrome，並將 Dusk 加入開發依賴。

```shell theme={null}
composer require laravel/dusk --dev
php artisan dusk:install
```

若要調整 ChromeDriver 版本，可使用 `dusk:chrome-driver` 指令。

```shell theme={null}
# 偵測與本機 Chrome 相容的版本並安裝
php artisan dusk:chrome-driver --detect
```

## 環境設定（`.env.dusk.local`）

若要使用 Dusk 專用的環境變數，請於專案根目錄建立 `.env.dusk.{environment}`。
本機環境使用 `.env.dusk.local`。

```ini theme={null}
APP_URL=http://127.0.0.1:8000
DB_CONNECTION=mysql
DB_DATABASE=app_testing
DB_USERNAME=root
DB_PASSWORD=root
```

Dusk 執行期間 `.env` 會被備份，並暫時套用 `.env.dusk.local` 的內容。

## 基本瀏覽器測試

以指令產生測試，並使用 `php artisan dusk` 執行。

```shell theme={null}
php artisan dusk:make LoginTest
php artisan dusk
```

只重新執行失敗的測試：

```shell theme={null}
php artisan dusk:fails
```

### 基本操作範例

```php theme={null}
<?php

namespace Tests\Browser;

use App\Models\User;
use Laravel\Dusk\Browser;
use Tests\DuskTestCase;

class LoginTest extends DuskTestCase
{
    public function test_user_can_login(): 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('/dashboard')
                ->assertSee('Dashboard');
        });
    }
}
```

`visit()`、`type()`、`press()`、`assertSee()` 是 Dusk 中最常見的操作。

<Warning>
  在 Dusk 測試中請勿使用 `RefreshDatabase`。如官方文件所述，應使用 `DatabaseMigrations` 或 `DatabaseTruncation` 來清除測試之間的資料。
</Warning>

## 頁面物件模式

當要測試複雜畫面時，可使用 `dusk:page` 建立頁面物件，讓程式更容易維護。

```shell theme={null}
php artisan dusk:page Login
```

在 `tests/Browser/Pages/Login.php` 定義 `url()` 或 `elements()`，測試端便可重複利用。

```php theme={null}
use Tests\Browser\Pages\Login;

$browser->visit(new Login)
    ->type('@email', 'taylor@laravel.com')
    ->type('@password', 'password')
    ->click('@submit')
    ->assertSee('Dashboard');
```

## 螢幕截圖與偵錯

排查失敗原因時，儲存螢幕截圖與 console 日誌會很有幫助。

```php theme={null}
$browser->screenshot('login-failed');
$browser->responsiveScreenshots('login-page');
$browser->screenshotElement('#login-form', 'login-form');
$browser->storeConsoleLog('login-console');
```

* 螢幕截圖：`tests/Browser/screenshots`
* Console 日誌：`tests/Browser/console`

## 在 CI（GitHub Actions）中執行

在 GitHub Actions 中，先啟動 ChromeDriver 與 Laravel 內建伺服器，再執行 `php artisan dusk`。

```yaml theme={null}
name: Dusk tests

on: [push, pull_request]

jobs:
  dusk:
    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@v5
      - run: cp .env.example .env
      - run: composer install --no-progress --prefer-dist --optimize-autoloader
      - run: php artisan key:generate
      - run: php artisan dusk:chrome-driver --detect
      - run: ./vendor/laravel/dusk/bin/chromedriver-linux --port=9515 &
      - run: php artisan serve --no-reload &
      - run: php artisan dusk
```

## Dusk 執行流程

```mermaid theme={null}
flowchart TD
    A["php artisan dusk"] --> B["備份 .env"]
    B --> C["套用 .env.dusk.local"]
    C --> D["啟動 ChromeDriver"]
    D --> E["執行瀏覽器測試<br>visit / type / click / assertSee"]
    E --> F{"是否失敗？"}
    F -->|Yes| G["儲存螢幕截圖與日誌"]
    F -->|No| H["測試完成"]
    G --> I["還原 .env"]
    H --> I
```

## 官方文件

<Card title="Laravel Dusk — 官方文件" icon="arrow-right" href="https://laravel.com/docs/dusk">
  Dusk 的完整 API（等待、斷言、鍵盤操作、iframe 操作等）請參考官方文件。
</Card>


## Related topics

- [Laravel Maestro — 啟動套件開發的協調器](/zh-TW/blog/maestro-introduction.md)
- [Laravel Sail](/zh-TW/sail.md)
- [Laravel Passkeys 初步調查（passkeys-server + @laravel/passkeys）](/zh-TW/blog/passkeys-introduction.md)
- [Laravel Telescope 實戰技巧](/zh-TW/blog/telescope-introduction.md)
- [Session](/zh-TW/session.md)
