> ## 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 运行浏览器 E2E 测试。

## 什么是 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');
```

## 截图与调试

排查失败原因时，保存截图和控制台日志会很有帮助。

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

* 截图：`tests/Browser/screenshots`
* 控制台日志：`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["运行 Browser 测试<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/blog/maestro-introduction.md)
- [Laravel Sail](/zh/sail.md)
- [Laravel Passkeys 初步调查(passkeys-server + @laravel/passkeys)](/zh/blog/passkeys-introduction.md)
- [Laravel Telescope 实战技巧](/zh/blog/telescope-introduction.md)
- [安装](/zh/installation.md)
