在 Puppeteer/Playwright 中通过标签文本选择输入

Coo*_*oop 6 puppeteer playwright

给出以下标记:

<label for="name">Name</label>
<input type="text" id="name" />
Run Code Online (Sandbox Code Playgroud)

我想在剧作家测试中填写输入值。但是,我更喜欢遵循类似于测试库的范例,它像真实用户一样使用选择器(通常是可见的文本内容)。因此,我希望我的剧作家选择器使用标签文本。

当我尝试以下操作时,我收到错误element is not an <input>,因为它选择了实际的标签元素: await page.fill('"Name"')

还有其他方法可以实现这一目标吗?

注意:我不热衷于使用 Playwright 测试库包,因为它还不够成熟。另外,我的理解是 Puppeteer 和 Playwright 实际上是相同的,因此为什么这个问题适用于这两个框架。

ggo*_*len 5

您可以使用.click()标签将焦点设置在输入上,然后用于page.keyboard.type在输入中键入内容。

这是 Puppeteer 中的一个最小示例:

const puppeteer = require("puppeteer");

let browser;
(async () => {
  browser = await puppeteer.launch({headless: true});
  const [page] = await browser.pages();
  await page.setContent(`
    <label for="name">Name</label>
    <input type="text" id="name" />
  `);
  await page.click("label[for='name']");
  await page.keyboard.type("hello world");
  console.log(await page.$eval("#name", e => e.value)); // => hello world
  console.log(await page.evaluate(() => document.activeElement.value)); // same
})()
  .catch(err => console.error(err))
  .finally(() => browser?.close());
Run Code Online (Sandbox Code Playgroud)

请注意,虽然剧作家和木偶师表面上看起来很相似,但截至撰写本文时,它们已经存在相当大的分歧。Playwright 已弃用大部分 Puppeteer 风格的 API,转而使用定位器,因此两个库之间的选择和操作现在有很大不同。

在撰写本文时,上述 Puppeteer 代码在 Playwright 中几乎可以正常工作,但惯用的、基于定位器的 Playwright 方法是:

const playwright = require("playwright"); // ^1.30.1

let browser;
(async () => {
  browser = await playwright.chromium.launch();
  const page = await browser.newPage();
  await page.setContent(`
    <label for="name">Name</label>
    <input type="text" id="name" />
  `);
  const input = page.getByLabel("name");
  await input.click();
  await page.keyboard.type("hello world");
  console.log(await input.inputValue()); // => hello world
  console.log(await page.evaluate(() => document.activeElement.value)); // same
})()
  .catch(err => console.error(err))
  .finally(() => browser?.close());
Run Code Online (Sandbox Code Playgroud)

附录,2023 年 8 月:Puppeteer 现在增加了对他们自己的实验定位器的支持。