You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 12:43:14