剧作家如何获取 div 内的所有链接,然后检查每个链接的结果是否为 200?

问题描述 投票:0回答:1

在高水平上,我想要

  1. 转到某个页面,然后使用一些定位器(div等)并在该定位器内拉出
    href
    标签的所有
    a
    链接。
  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.

在 Playwright 中甚至可以做到这一点吗?也就是说,首先获取页面 div 等上的所有链接,然后并行地访问每个链接以检查其 statusCode?

javascript node.js parallel-processing automated-tests playwright
1个回答
0
投票

我会使用

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.badurlthatdoesntexist.com">x</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);
  }
});

为了加快速度,您可以使用任务队列库,或者,不太优化但依赖项较少,以大小为 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 = 4;

  for (let i = 0; i < links.length; i += chunk) {
    await Promise.all(links.slice(i, i + chunk).map(e => request.get(e)));
  }
});
© www.soinside.com 2019 - 2024. All rights reserved.