关于 laravel-dusk
面向为 Laravel 应用编写浏览器与端到端测试的开发者的 Laravel Dusk 技能,涵盖浏览器交互、可靠等待、页面对象组织和测试排错。
主要功能
- 01浏览器交互示例
- 02稳定的 Dusk 选择器
- 03显式等待策略
- 04页面对象组织方式
- 05表单与 JavaScript 测试
- 06数据库与驱动配置指导
适用场景
- 01测试登录和表单提交流程
- 02验证动态 JavaScript 界面
- 03组织可复用的浏览器测试
- 04排查不稳定的浏览器测试
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ rawveg/ skillsforge-marketplace --skill laravel-dusk安装后在 Claude Code 中输入/laravel-dusk确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
plugin.jsonreferences/index.mdother.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 对话框或键盘宏等高级主题
使用此技能
入门指南
- 从基本测试开始:使用简单的
visit()、type()、press()和assertSee()方法 - 使用 Dusk 选择器:在 HTML 中添加
dusk属性,以获得稳定的选择器 - 了解等待机制:始终使用
waitFor(),而不是pause(),以确保测试可靠 - 运行测试:执行
php artisan dusk查看结果
中级用户
- 实现页面对象:使用 Page 模式组织复杂测试
- 使用数据库特征:在
DatabaseMigrations和DatabaseTruncation之间选择 - 创建浏览器宏:为常见工作流定义可复用的方法
- 测试身份验证:使用
loginAs()跳过登录界面 - 处理 JavaScript:使用
waitUntil()等待动态内容和 AJAX
高级用户
- 多浏览器测试:使用多个浏览器测试实时功能
- 自定义等待逻辑:使用
waitUsing()处理复杂条件 - 组件模式:为共享 UI 元素创建可复用组件
- CI/CD 集成:在 GitHub Actions、Travis CI 或其他平台中设置 Dusk
- 替代驱动程序:配置 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
资源
官方文档
- Laravel Dusk 文档:https://laravel.com/docs/12.x/dusk
- API 参考:参阅
references/other.md,查看完整的方法列表
参考文件中的常见模式
参考文档包括:
- 70+ 个带说明的断言方法
- 完整的表单交互 API
- 等待策略和计时最佳实践
- 页面对象模式示例
- 浏览器宏定义
- CI/CD 配置示例
- 特定环境的测试设置
最佳实践
- 使用 Dusk 选择器(
dusk属性),而非 CSS 类,以提高稳定性 - 明确等待,使用
waitFor()方法,而不是任意调用pause() - 使用页面对象组织复杂测试场景
- 利用数据库截断,加快测试执行
- 创建浏览器宏,处理频繁重复的操作
- 使用
with()或elsewhere()限定选择器范围,指定页面区域 - 测试用户行为,而不是实现细节
- 使用身份验证快捷方式(如
loginAs())跳过登录流程 - 使用
screenshot()截取屏幕截图,调试失败原因 - 将相关测试分组,并使用
--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