Playwright点击第二个ul下第二个li报错,求正确实现方案
问题描述
我正在测试网页的footer元素,测试目标是逐个点击每个ul的前3个li并验证跳转链接。但尝试点击第二个ul下的第二个li时,出现「locator.click: Target closed」错误,相关信息如下:
HTML结构
<footer id="main-footer" class="section-footer mt-5 border-top"> ...(完整结构见原文) </footer>
原测试代码
await page.waitForSelector(".footer-menu", {timeout: 10000}) const unorderedList = await page.locator('.footer-menu:nth-child(1) li:nth-child(2)'); unorderedList.click();
错误信息
Running 1 test using 1 worker 1) [chromium] › footer-try.spec.ts:3:5 › has title ─────────────────────────────────────────────── locator.click: Target closed =========================== logs =========================== waiting for locator('.footer-menu:nth-child(1) li:nth-child(2)') ============================================================ 9 | const unorderedList = await page.locator('.footer-menu:nth-child(1) li:nth-child(2)'); 10 | > 11 | unorderedList.click(); | ^ 12 | 13 | // class="" 14 | at D:\PKL\Playwright\Test WebInter\playwright.web.id\tests\footer-try.spec.ts:11:17 Test timeout of 0ms exceeded while tearing down "context". 1 failed [chromium] › footer-try.spec.ts:3:5 › has title
解决方案
「Target closed」通常是因为点击前元素已被移除、页面跳转导致上下文失效,或者定位器匹配的元素不稳定。以下是修复后的Playwright实现代码,同时满足逐个点击每个ul前3个li并验证跳转链接的需求:
import { test, expect } from '@playwright/test'; test('验证footer所有ul前3个li跳转链接', async ({ page }) => { await page.goto('你的目标页面URL'); // 精准定位footer下的所有ul元素 const footerUlList = page.locator('#main-footer .footer-menu'); const ulCount = await footerUlList.count(); for (let ulIndex = 0; ulIndex < ulCount; ulIndex++) { // 获取当前ul下的前3个li元素 const currentUl = footerUlList.nth(ulIndex); const liList = currentUl.locator('li').range(0, 3); const liCount = await liList.count(); for (let liIndex = 0; liIndex < liCount; liIndex++) { const currentLi = liList.nth(liIndex); // 前置校验:确保元素可见且可交互 await expect(currentLi).toBeVisible({ timeout: 10000 }); await expect(currentLi).toBeEnabled(); // 获取li内的链接地址 const linkElement = currentLi.locator('a'); const linkHref = await linkElement.getAttribute('href'); expect(linkHref).not.toBeNull(); // 处理页面跳转:监听导航事件,避免上下文中断 const navigationPromise = page.waitForNavigation({ waitUntil: 'domcontentloaded' }); const popupPromise = page.waitForEvent('popup'); await currentLi.click(); // 判断是当前页面跳转还是新弹窗 const newPage = await Promise.race([navigationPromise, popupPromise]); // 验证跳转后的URL if (newPage instanceof page.constructor) { // 新标签页跳转的情况 expect(newPage.url()).toContain(linkHref!); await newPage.close(); await page.bringToFront(); } else { // 当前页面跳转的情况 expect(page.url()).toContain(linkHref!); // 若需要返回原页面继续测试,可添加:await page.goBack(); } } } });
关键修复说明
- 精准定位:通过
#main-footer .footer-menu锁定footer下的ul,避免nth-child因DOM结构变动导致的匹配错误 - 元素状态校验:点击前强制验证元素可见、可交互,确保元素未被提前销毁
- 跳转事件监听:通过
waitForNavigation和waitForEvent处理不同类型的页面跳转,避免上下文关闭错误 - 批量遍历逻辑:循环处理所有ul及每个ul的前3个li,完整覆盖测试目标
- 链接验证:获取链接属性并校验跳转后的URL符合预期
内容的提问来源于stack exchange,提问作者Dede Yudi
相关产品推荐
相关产品推荐

