mcpField
L
laravel-dusk

laravel-dusk

github.com/rawveg测试与质量4037 次安装36 周前更新
代码仓库

关于 laravel-dusk

面向为 Laravel 应用编写浏览器与端到端测试的开发者的 Laravel Dusk 技能,涵盖浏览器交互、可靠等待、页面对象组织和测试排错。

主要功能

  1. 01浏览器交互示例
  2. 02稳定的 Dusk 选择器
  3. 03显式等待策略
  4. 04页面对象组织方式
  5. 05表单与 JavaScript 测试
  6. 06数据库与驱动配置指导

适用场景

  1. 01测试登录和表单提交流程
  2. 02验证动态 JavaScript 界面
  3. 03组织可复用的浏览器测试
  4. 04排查不稳定的浏览器测试

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/rawveg/skillsforge-marketplace --skill laravel-dusk

安装后在 Claude Code 中输入/laravel-dusk确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

plugin.json
references/
index.md
other.md

详细介绍

Laravel Dusk 技能

全面协助使用 Laravel Dusk 进行浏览器自动化和测试,为你提供专业指导,帮助你为 Laravel 应用编写清晰易用的浏览器测试。

何时使用此技能

在以下情况下应触发此技能:

  • 为 Laravel 编写或调试浏览器自动化测试
  • 测试用户界面和 JavaScript 交互
  • 实现端到端(E2E)测试工作流
  • 在 Laravel 应用中设置自动化 UI 测试
  • 处理表单提交、身份验证流程或页面导航测试
  • 配置 ChromeDriver 或其他浏览器驱动
  • 使用 Page Object 模式组织测试
  • 测试 Vue.js 组件或等待 JavaScript 事件
  • 排查浏览器测试失败或时序问题

快速参考

1. 基本浏览器测试
public function testBasicExample(): void
{
    $this->browse(function (Browser $browser) {
        $browser->visit('/login')
            ->type('email', '[email protected]')
            ->type('password', 'password')
            ->press('Login')
            ->assertPathIs('/home');
    });
}
2. 使用 Dusk 选择器(推荐)

<button dusk="login-button">Login</button>
<input dusk="email-input" name="email" />
// In your test - use @ prefix for dusk selectors
$browser->type('@email-input', '[email protected]')
    ->click('@login-button');
3. 测试多个浏览器
public function testMultiUserInteraction(): void
{
    $this->browse(function (Browser $first, Browser $second) {
        $first->loginAs(User::find(1))
            ->visit('/home');

        $second->loginAs(User::find(2))
            ->visit('/home');
    });
}
4. 等待元素
// Wait for element to appear
$browser->waitFor('.modal')
    ->assertSee('Confirmation Required');

// Wait for text to appear
$browser->waitForText('Hello World');

// Wait for JavaScript condition
$browser->waitUntil('App.data.servers.length > 0');

// Wait when element is available
$browser->whenAvailable('.modal', function (Browser $modal) {
    $modal->assertSee('Delete Account')
        ->press('OK');
});
5. 表单交互
// Text input
$browser->type('email', '[email protected]')
    ->append('notes', 'Additional text')
    ->clear('description');

// Dropdown selection
$browser->select('size', 'Large')
    ->select('categories', ['Art', 'Music']); // Multiple

// Checkboxes and radio buttons
$browser->check('terms')
    ->radio('gender', 'male');

// File upload
$browser->attach('photo', __DIR__.'/photos/profile.jpg');
6. Page Object 模式
// Generate page object
// php artisan dusk:page Login

// app/tests/Browser/Pages/Login.php
class Login extends Page
{
    public function url(): string
    {
        return '/login';
    }

    public function elements(): array
    {
        return [
            '@email' => 'input[name=email]',
            '@password' => 'input[name=password]',
            '@submit' => 'button[type=submit]',
        ];
    }

    public function login(Browser $browser, $email, $password): void
    {
        $browser->type('@email', $email)
            ->type('@password', $password)
            ->press('@submit');
    }
}

// Use in test
$browser->visit(new Login)
    ->login('[email protected]', 'password')
    ->assertPathIs('/dashboard');
7. 浏览器宏(可复用方法)
// In AppServiceProvider or DuskServiceProvider
use Laravel\Dusk\Browser;

Browser::macro('scrollToElement', function (string $element) {
    $this->script("$('html, body').animate({
        scrollTop: $('{$element}').offset().top
    }, 0);");

    return $this;
});

// Use in tests
$browser->scrollToElement('#footer')
    ->assertSee('Copyright 2024');
8. 测试中的数据库管理
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTruncation;

class ExampleTest extends DuskTestCase
{
    // Option 1: Run migrations before each test (slower)
    use DatabaseMigrations;

    // Option 2: Truncate tables after first migration (faster)
    use DatabaseTruncation;

    // Exclude specific tables from truncation
    protected $exceptTables = ['migrations'];
}
9. 执行 JavaScript
// Execute JavaScript
$browser->script('document.documentElement.scrollTop = 0');

// Get JavaScript return value
$path = $browser->script('return window.location.pathname');

// Wait for reload after action
$browser->waitForReload(function (Browser $browser) {
    $browser->press('Submit');
})->assertSee('Success');
10. 常用断言
// Page assertions
$browser->assertPathIs('/dashboard')
    ->assertRouteIs('dashboard')
    ->assertTitle('Dashboard')
    ->assertSee('Welcome Back')
    ->assertDontSee('Error');

// Form assertions
$browser->assertInputValue('email', '[email protected]')
    ->assertChecked('remember')
    ->assertSelected('role', 'admin')
    ->assertEnabled('submit-button');

// Element assertions
$browser->assertVisible('.success-message')
    ->assertMissing('.error-alert')
    ->assertPresent('button[type=submit]');

// Authentication assertions
$browser->assertAuthenticated()
    ->assertAuthenticatedAs($user);

核心概念

Dusk 选择器与 CSS 选择器

Dusk 选择器(推荐)使用 HTML dusk 属性,不会随 UI 更新而改变:

  • 比 CSS 类或 ID 更稳定
  • 明确标记用于测试的元素
  • 在测试中使用 @ 前缀:$browser->click('@submit-button')
  • 添加到 HTML 中:<button dusk="submit-button">Submit</button>

CSS 选择器更容易失效,但有时不可或缺:

  • .class-name、#id、div > button
  • HTML 结构变化时可能失效
  • 在无法控制 HTML 时使用
等待策略

始终显式等待,而不要使用随意的暂停:

  • waitFor('.selector') - 等待元素出现
  • waitUntilMissing('.selector') - 等待元素消失
  • waitForText('text') - 等待文本出现
  • waitUntil('condition') - 等待 JavaScript 条件满足
  • whenAvailable('.selector', callback) - 元素可用时运行回调
Page Object

将复杂的测试逻辑整理到 Page 类中:

  • 定义 URL、断言和元素选择器
  • 为特定页面的操作创建可复用方法
  • 提高测试的可读性和可维护性
  • 使用以下命令生成:php artisan dusk:page PageName
浏览器宏

为常见模式定义可复用的浏览器方法:

  • 在服务提供者的 boot() 方法中注册
  • 在所有测试中使用
  • 像内置方法一样链式调用
  • 示例:滚动、模态框交互、自定义断言

参考文件

此技能在 references/ 中包含全面的文档:

  • other.md - 完整的 Laravel Dusk 文档,涵盖:
    • 安装和配置
    • ChromeDriver 管理
    • 测试生成和执行
    • 浏览器交互方法
    • 表单处理和文件上传
    • 等待策略和断言
    • Page Object 和组件模式
    • CI/CD 集成示例

需要以下内容时,请使用参考文件:

  • 特定方法的详细 API 文档
  • 可用断言的完整列表(70+)
  • 不同环境的配置选项
  • iframe、JavaScript 对话框或键盘宏等高级主题

使用此技能

入门指南
  1. 从基本测试开始:使用简单的 visit()、type()、press() 和 assertSee() 方法
  2. 使用 Dusk 选择器:在 HTML 中添加 dusk 属性,以获得稳定的选择器
  3. 了解等待机制:始终使用 waitFor(),而不是 pause(),以确保测试可靠
  4. 运行测试:执行 php artisan dusk 查看结果
中级用户
  1. 实现页面对象:使用 Page 模式组织复杂测试
  2. 使用数据库特征:在 DatabaseMigrations 和 DatabaseTruncation 之间选择
  3. 创建浏览器宏:为常见工作流定义可复用的方法
  4. 测试身份验证:使用 loginAs() 跳过登录界面
  5. 处理 JavaScript:使用 waitUntil() 等待动态内容和 AJAX
高级用户
  1. 多浏览器测试:使用多个浏览器测试实时功能
  2. 自定义等待逻辑:使用 waitUsing() 处理复杂条件
  3. 组件模式:为共享 UI 元素创建可复用组件
  4. CI/CD 集成:在 GitHub Actions、Travis CI 或其他平台中设置 Dusk
  5. 替代驱动程序:配置 Selenium Grid 或 ChromeDriver 之外的其他浏览器
导航提示
  • 快速示例:查看上方的快速参考部分,了解常见模式
  • 方法文档:参阅 other.md,查看完整的 API 参考
  • 断言列表:参考文件包含全部 70+ 个可用断言
  • 配置:查看参考文件,了解环境设置和驱动程序选项
  • 最佳实践:在参考文档中查找“最佳实践”部分

安装与设置

# Install Laravel Dusk
composer require laravel/dusk --dev

# Run installation
php artisan dusk:install

# Update ChromeDriver
php artisan dusk:chrome-driver

# Make binaries executable (Unix)
chmod -R 0755 vendor/laravel/dusk/bin/

# Run tests
php artisan dusk

常用命令

# Generate new test
php artisan dusk:make LoginTest

# Generate page object
php artisan dusk:page Dashboard

# Generate component
php artisan dusk:component Modal

# Run all tests
php artisan dusk

# Run specific test
php artisan dusk tests/Browser/LoginTest.php

# Run failed tests only
php artisan dusk:fails

# Run with filter
php artisan dusk --group=authentication

# Update ChromeDriver
php artisan dusk:chrome-driver --detect

资源

官方文档
参考文件中的常见模式

参考文档包括:

  • 70+ 个带说明的断言方法
  • 完整的表单交互 API
  • 等待策略和计时最佳实践
  • 页面对象模式示例
  • 浏览器宏定义
  • CI/CD 配置示例
  • 特定环境的测试设置

最佳实践

  1. 使用 Dusk 选择器(dusk 属性),而非 CSS 类,以提高稳定性
  2. 明确等待,使用 waitFor() 方法,而不是任意调用 pause()
  3. 使用页面对象组织复杂测试场景
  4. 利用数据库截断,加快测试执行
  5. 创建浏览器宏,处理频繁重复的操作
  6. 使用 with() 或 elsewhere() 限定选择器范围,指定页面区域
  7. 测试用户行为,而不是实现细节
  8. 使用身份验证快捷方式(如 loginAs())跳过登录流程
  9. 使用 screenshot() 截取屏幕截图,调试失败原因
  10. 将相关测试分组,并使用 --group 标志定向执行

故障排除

常见问题

ChromeDriver 版本不匹配:

php artisan dusk:chrome-driver --detect

未找到元素:

  • 交互前先使用 waitFor('.selector')
  • 检查元素是否位于 iframe 中
  • 使用浏览器开发者工具验证选择器

测试随机失败:

  • 使用明确的等待替换 pause()
  • 增加超时时间:waitFor('.selector', 10)
  • 使用 waitUntil() 等待 JavaScript 条件

数据库状态问题:

  • 使用 DatabaseTruncation 特征
  • 在 setUp() 方法中重置数据
  • 检查应用程序代码中是否存在事务

备注

  • Laravel Dusk 默认使用 ChromeDriver(无需 Selenium/JDK)
  • 支持通过 Selenium WebDriver 协议使用其他浏览器
  • 测试存储在 tests/Browser 目录中
  • 页面对象存放在 tests/Browser/Pages
  • 失败时,屏幕截图保存到 tests/Browser/screenshots
  • 调试用的控制台日志保存到 tests/Browser/console

评论

支持 Markdown