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

Playwright+PO模式下获取元素总数失败:Target closed报错求解

修复Playwright中"Target closed"错误(库存页元素计数问题)

在基于Page Object模式的Playwright自动化测试中,尝试获取https://www.saucedemo.com/inventory.html页面中商品元素总数时,出现以下错误:

Error: locator.waitFor: Target closed
=========================== logs ===========================
waiting for locator('xpath=//div[@class="inventory_item"]') to be visible
============================================================

   at ../pages/InventoryPage.ts:19

  17 |
  18 | async selectRandomItem(){
> 19 |   await this.colTable.waitFor({state: "visible"}); //issue is here
     |                       ^
  20 |   const itemCount = await this.colTable.count();
  21 |   return await itemCount;
  22 | }

核心修复步骤

1. 确保登录后页面完全加载

登录操作完成后,必须等待页面成功跳转到库存页,避免在页面未就绪时执行元素操作。有两种实现方式:

方式一:在LoginPage的login方法中添加页面跳转等待

修改LoginPage.ts中的login方法:

async login(username: string, password: string) {
  // 原有输入用户名、密码、点击登录按钮的逻辑
  await this.page.waitForURL('**/inventory.html'); // 等待跳转到库存页
}

方式二:在测试步骤中等待页面标识元素

在测试用例的登录步骤后,等待库存页的标题元素出现:

await test.step("2.输入正确的用户名和密码", async () => {
  await loginPage.login("standard_user", "secret_sauce");
  await inventoryPage.lblLoggedIn.waitFor(); // 等待"Products"标题出现,确认页面加载完成
});

2. 正确await异步函数

测试用例中调用selectRandomItem()时,必须使用await获取返回值,否则会直接打印Promise对象,同时导致时序混乱:

await test.step("3.获取元素总数", async () => {
  const itemCount = await inventoryPage.selectRandomItem();
  console.log(itemCount);
});

3. 优化元素等待与计数逻辑

Playwright的count()方法默认会等待元素出现,无需额外调用waitFor,可以简化代码:

async selectRandomItem(){
  const itemCount = await this.colTable.count();
  return itemCount;
}

如果需要显式等待,建议使用state: "attached"(等待元素加入DOM)替代visible,避免因元素暂时不可见导致的错误:

async selectRandomItem(){
  await this.colTable.waitFor({state: "attached"});
  const itemCount = await this.colTable.count();
  return itemCount;
}

4. 优化元素定位器

推荐使用Playwright更稳定的定位方式替代XPath,比如基于class的定位:

this.colTable = page.locator('.inventory_item'); // 等效于原XPath,更简洁

修改后的完整代码示例

inventory.spec.ts

import { test, expect } from '@playwright/test';
import { LoginPage } from '../pages/LoginPage';
import { InventoryPage } from '../pages/InventoryPage';

test.describe("库存页测试", () => {

  let loginPage: LoginPage;
  let inventoryPage: InventoryPage;

  test.beforeEach(({ page }) => {
    loginPage = new LoginPage(page);
    inventoryPage = new InventoryPage(page);
  });

  test("TC-003: 验证随机商品可添加到购物车", async ({ page }) => {
    await test.step("1.访问登录页", async () => {
      await loginPage.visit();
    });
    await test.step("2.输入正确的用户名和密码", async () => {
      await loginPage.login("standard_user", "secret_sauce");
      await inventoryPage.lblLoggedIn.waitFor(); // 等待页面加载完成
    });
    await test.step("3.获取商品总数", async () => {
      const itemCount = await inventoryPage.selectRandomItem();
      console.log(itemCount);
    });
  });
});

InventoryPage.ts

import { Locator, Page } from "@playwright/test";

export class InventoryPage {

  readonly page: Page;
  readonly lblLoggedIn: Locator;
  readonly colTable: Locator;
 
  constructor(page: Page){
    this.page = page;
    this.lblLoggedIn = page.getByText('Products');
    this.colTable = page.locator('.inventory_item'); // 简化定位器
  }

  async selectRandomItem(){
    const itemCount = await this.colTable.count(); // 无需额外waitFor
    return itemCount;
  }
}

内容的提问来源于stack exchange,提问作者AVI

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 17:05:37