在更高的层面上,我想

  1. 转到某个页面,然后使用某个定位器(div等),在这个定位器中拉出a个标签的所有href个链接.
  2. 然后我想要单独转到每个链接,看看它是否有效,或者是一个断开的链接,这意味着判断状态代码是否为200.
  3. 这里需要注意的是,第二个点应该并行运行,否则以串行方式判断每个链接将非常慢.

这是我目前拥有的代码(我已经删除了一些敏感信息,如URL等).

test.describe(`@Header Tests`, () => {
  test.beforeEach(async ({ page, context }) => {
    await page.goto(".....some url.....");
  });
  test(`@smoke Validate all header links give a status of 200`, async ({
    page,
  }) => {
    const elements = page.locator("section#mega-nav a");
    const links = await elements.evaluateAll<string[], HTMLAnchorElement>(
      (itemTexts) =>
        itemTexts
          .map((item) => item.href)
          .filter((href) => href !== "" && !href.includes("javascript:"))
    );

    // visit each link
    for (const link of links) {
      test(`Check status code for ${link}`, async () => {
        // Visit the link
        const response = await page.goto(link, {
          waitUntil: "domcontentloaded",
        });

        // Check if the response status code is 200
        expect(response?.status()).toBe(200);
      });
    }
  });
});

但当我运行此命令时,我收到以下错误

    Error: Playwright Test did not expect test() to be called here.
    Most common reasons include:
    - You are calling test() in a configuration file.
    - You are calling test() in a file that is imported by the configuration file.
    - You have two different versions of @playwright/test. This usually happens
      when one of the dependencies in your package.json depends on @playwright/test.

在剧作家身上能做到这一点吗?也就是说,首先获取页面div等上的所有链接,然后并行地转到每个链接以判断它们的状态代码?

推荐答案

我会用request而不是page.goto:

import {test} from "@playwright/test"; // ^1.41.2

const html = `<!DOCTYPE html><html><body>
<a href="https://news.ycombinator.com">yc</a>
<a href="https://www.example.com">example</a>
<a href="https://www.stackoverflow.com">so</a>
<a href="https://www.badurlthatdoesntexist.com">bad url</a>
</body></html>`;

test("all links are valid", async ({page, request}) => {
  await page.setContent(html);
  const links = await page.locator("a")
    .evaluateAll(els => els.map(el => el.href));

  for (const link of links) {
    await request.get(link);
  }
});

(go 掉www.badurlthatdoesntexist.com即可查看测试通过)

为了加快这一速度,您可以使用任务队列(手动或库).或者,您可以使用大小为N的块进行迭代,并使用Promise.all来并行化每个块,这是一种不太理想的做法,但代码简单且没有依赖关系:

test("all links are valid", async ({page, request}) => {
  await page.setContent(html);
  const links = await page.locator("a")
    .evaluateAll(els => els.map(el => el.href));
  const chunk = 3;

  for (let i = 0; i < links.length; i += chunk) {
    await Promise.all(links.slice(i, i + chunk).map(e => request.get(e)));
  }
});

Javascript相关问答推荐

为什么getRecord()会因为与_logger相关的错误而失败?(使用Hedera SDK)

使用AJX发送表单后,$_Post看起来为空

提交表格后保留Web表格中的收件箱值?

GrapeJS -如何保存和加载自定义页面

如何找出摆线表面上y与x相交的地方?

在服务器上放置了Create Reaction App Build之后的空白页面

空的结果抓取网站与Fetch和Cheerio

Chromium会将URL与JS一起传递到V8吗?

JSDoc创建并从另一个文件导入类型

Javascript json定制

PDF工具包阿拉伯字体的反转数字

使用Java脚本导入gltf场景并创建边界框

不能将空字符串传递给cy.containes()

查询参数中的JAVASCRIPT/REACT中的括号

Webpack在导入前混淆文件名

面对代码中的错误作为前端与后端的集成

为列表中的项目设置动画

在SuperBase JS客户端中寻址JSON数据

如何使用Reaction路由导航测试挂钩?

为什么我的SoupRequest";被重置为初始值,以及如何修复它?