在 k6 浏览器自动化测试中,`page.waitfornavigation()` 无法可靠捕获多步重定向后的最终页面状态,导致 `page.title()` 返回中间页标题;根本原因在于导航超时、上下文默认限制及缺乏对目标页面就绪状态的精准断言。
K6 的 k6/experimental/browser 模块基于 Playwright 内核,但其默认行为(如 waitForNavigation 的隐式超时、上下文级超时继承)与真实浏览器交互存在差异,尤其在涉及多跳重定向(如登录流程中的 /login → /auth → /dashboard)时极易出现“假完成”问题——即导航事件被过早触发,而 DOM 尚未渲染或关键资源未加载。
导航完成 ≠ 页面可用。应等待业务语义明确的元素(如仪表盘标题、用户头像、主内容区 ID)出现在 DOM 中:
// ✅ 正确做法:等待最终页核心元素
await Promise.all([
page.waitForSelector('#dashboard-welcome-title', { timeout: 30000 }),
continueButton2.click(),
]);
console.log(await page.title()); // 此时 title 必为最终页⚠️ 注意:#dashboard-welcome-title 需替换为实际页面中仅在目标页存在且稳定渲染的选择器(避免 class 动态生成或 SSR/CSR 混合导致的竞态)。
waitForNavigation 默认超时约 30s,但 K6 上下文(Context)和页面(Page)可能继承更短的全局 timeout。需逐层覆盖:
const browser = chromium.launch({
headless: false,
timeout: '120s', // Browser 实例超时
slowMo: '500ms',
});
const context = browser.newContext({
timeout: '120s', // ✅ 关键:Context 级超时(影响 waitForNavigation 等)
});
const page = context.newPage();
// 同时为单次等待指定超时(防御性编程)
await page.waitForSelector('#final-page-element', { timeout: 45000 });sleep(10) 是反模式:既无法保证页面就绪(慢网/高负载下仍失败),又拖慢执行效率。所有等待必须基于可观测状态:
// ❌ 错误:固定休眠
sleep(10);
// ✅ 正确:条件化等待 + 超时兜底
await page.waitForFunction(
() => document.querySelector('#app')?.dataset.ready === 'true',
{ timeout: 60000 }
);export async function browser() {
const browser = chromium.launch({
headless: false,
timeout: '120s',
slowMo: '500ms',
});
const context = browser.newContext({ timeout: '120s' }); // ← 关键补充
const page = context.newPage();
await page.goto('http://localhost:5000/', { waitUntil: 'networkidle' });
// Cookie banner
await page.locator('//*[@id="cookies-banner"]/div/div[2]/button').click();
// Company input & continue
await page.locator('#company-input').type('Test1');
await Promise.all([
page.waitForSelector('#login-method-selection-password-login-button', { timeout: 30000 }),
page.locato
r('#company-login-continue-button').click(),
]);
// Password login
await Promise.all([
page.waitForSelector('#user-name-input', { timeout: 30000 }), // 确保登录表单已加载
page.locator('//*[@id="login-method-selection-password-login-button"]/p').click(),
]);
// Final submit → wait for dashboard element
await page.locator('#user-name-input').type('TestUsername');
await page.locator('#password-input').type('TestPassword');
await Promise.all([
page.waitForSelector('#dashboard-main-content', { timeout: 45000 }), // ← 目标页唯一标识
page.locator('//*[@id="password-login-continue-button"]/p').click(),
]);
console.log('Final page title:', await page.title());
console.log('URL:', page.url());
await page.close();
await browser.close();
}通过以上调整,可彻底解决重定向后 page.title() 返回错误标题的问题,并显著提升测试稳定性与可维护性。