本文目录导读:

在 Laravel 中进行浏览器测试时,处理等待元素是一个常见需求,以下是几种有效的解决方案:
使用 Laravel Dusk 的内置等待方法
基本等待方法
use Laravel\Dusk\Browser;
$browser->visit('/login')
// 等待元素可见
->waitFor('#email')
// 等待元素出现(不一定可见)
->waitForText('登录')
// 等待元素消失
->waitUntilMissing('#loading')
// 等待指定时间(毫秒)
->pause(1000);
带条件的等待
$browser->visit('/dashboard')
// 等待元素可见并设置超时时间
->waitFor('.chart', 10) // 最多等待10秒
// 等待元素包含特定文本
->waitForText('欢迎回来', 5)
// 等待元素可点击
->waitForEnabled('#submit-btn')
// 等待 URL 变化
->waitForLocation('/home')
// 使用回调函数
->waitUntil('document.readyState === "complete"', 10);
使用 jQuery 选择器
$browser->visit('/products')
// 等待特定类名的元素出现
->waitFor('.product-card', 15)
// 等待具有特定属性的元素
->waitFor('[data-testid="add-to-cart"]')
// 等待包含特定元素的出现
->waitFor('div.product-card:contains("iPhone")');
自定义等待方法
在测试用例中定义辅助方法:
class ExampleTest extends DuskTestCase
{
public function test_wait_for_ajax_loading()
{
$this->browse(function (Browser $browser) {
$browser->visit('/data-page')
// 等待 Ajax 加载完成
->waitUntil('!document.querySelector(".loading-spinner")')
->assertSee('数据加载完成');
});
}
// 自定义等待方法
protected function waitForAjaxComplete(Browser $browser)
{
return $browser->waitUntil(
'typeof jQuery === "undefined" || jQuery.active === 0'
);
}
}
处理动态内容的最佳实践
等待多个元素
$browser->visit('/page')
->waitFor('.header')
->waitFor('.content')
->waitFor('.footer');
使用循环等待轮询
$browser->waitUntil(function () {
return $this->driver->findElements(
WebDriverBy::cssSelector('.dynamic-content')
) !== [];
}, 10);
配置等待超时
在 DuskTestCase 中配置全局超时:
// tests/DuskTestCase.php
class DuskTestCase extends BaseTestCase
{
protected function driver()
{
$options = (new ChromeOptions)->addArguments([
'--disable-gpu',
'--headless',
'--window-size=1920,1080',
'--no-sandbox',
]);
return RemoteWebDriver::create(
'http://localhost:9515',
DesiredCapabilities::chrome()->setCapability(
ChromeOptions::CAPABILITY,
$options
)
);
}
// 配置默认等待时间
protected function maxWaitTime()
{
return 15; // 15秒
}
}
实际应用示例
class UserInteractionTest extends DuskTestCase
{
public function test_form_submission_with_loading()
{
$this->browse(function (Browser $browser) {
$browser->visit('/create-user')
->type('name', 'John Doe')
->type('email', 'john@example.com')
->click('#submit')
// 等待提交按钮变成禁用状态
->waitFor('.btn-disabled')
// 等待成功提示出现
->waitForText('用户创建成功')
// 等待重定向或新页面加载
->waitForLocation('/users')
->assertSee('John Doe');
});
}
}
处理 SPA 应用的等待
$browser->visit('/vue-application')
// 等待 Vue 渲染完成
->waitUntil('document.querySelector("#app").innerHTML.includes("期望文本")')
// 等待 Vue 路由加载
->waitFor('[data-route="home"]')
// 等待动态组件加载
->waitUntil('!document.querySelector(".loading")');
选择合适的方法取决于你的具体场景:
- waitFor:最常用的等待方法
- waitForText:等待特定文本出现
- pause:固定时间等待(不推荐,可能不稳定)
- waitUntil:最灵活,可以自定义等待条件
记得始终设置合理的超时时间,避免测试挂起影响整体执行效率。