laravel dusk 默认启用无头模式,因 php artisan dusk 启动时自动向 chromedriver 传入 --headless 等参数,适配 ci/cd;但本地调试需关闭该模式以可视化操作、精准排查 js 渲染与 dom 状态问题。

默认就是无头模式,不需要额外配置;但调试时关掉它反而更高效。
为什么 Laravel Dusk 默认用无头 Chrome
因为 php artisan dusk 启动时自动调用 ChromeDriver 并传入 --headless、--no-sandbox 等标志,适合 CI/CD 环境运行,不依赖桌面环境。但这也带来两个实际问题:
- 本地开发时看不到页面跳转过程,断点式调试困难
- 某些 JS 行为(如
matchMedia检测、部分 Canvas 渲染)在无头模式下表现不同 - 报错截图有时无法准确反映真实渲染状态(比如元素被遮挡但无头模式没触发)
如何临时关闭无头模式看真实浏览器
修改 tests/DuskTestCase.php 中的 driver 方法,在 ChromeOptions 实例中移除或注释掉 headless 相关参数:
$options = new ChromeOptions; // $options->addArguments(['--headless', '--no-sandbox', '--disable-gpu']); $options->addArguments(['--window-size=1920,1080']);
再运行 php artisan dusk,就会弹出真实 Chrome 窗口。注意:此时不能同时运行多个测试(会抢端口),建议只跑单个测试文件:
php artisan dusk --filter=testLoginFlow- 或直接指定文件:
php artisan dusk tests/Browser/LoginTest.php
截图和等待不是万能的,得看 DOM 真实状态
waitFor 只检查元素是否“存在”或“可见”,但不保证 JS 已完成初始化。比如 Vue 组件可能已挂载,但异步数据还没返回,assertSee 就会误判成功。
- 优先用
$browser->waitForText('Loaded')而非$browser->assertSee('Loaded') - 截图保存在
tests/Browser/screenshots/,但别只看图——配合$browser->dump()输出当前 HTML 片段更准 - 遇到“元素找不到”但肉眼可见,大概率是 iframe 或 Shadow DOM,需用
$browser->withinFrame或原生 JS 查找
环境隔离容易被忽略的细节
很多人以为改 .env 就够了,但 Dusk 运行时读的是 .env.dusk.local(不是 .env.testing)。如果漏配这个文件:
- 数据库写入测试数据会污染本地开发库
- 邮件发送可能真发出去(哪怕用了
log驱动,路径也可能不对) -
APP_URL写成http://localhost会导致跨域或重定向失败
务必确保 .env.dusk.local 存在且包含独立数据库名、APP_URL=http://127.0.0.1:8000、MAIL_MAILER=log 等关键项。











