如何使用 Puppeteer 从输入中删除现有文本?

How to delete existing text from input using Puppeteer?

我正在尝试在包含当前记录标题的可编辑输入中测试修改文本 - 我希望能够测试编辑此类文本,将其替换为其他内容。

我知道我可以使用 await page.type('#inputID', 'blah'); 将 "blah" 插入文本框(在我的例子中,有现有文本,只附加 "blah"),但是,我找不到任何允许删除或替换现有文本的页面方法1

您可以根据需要使用 page.evaluate 来操纵 DOM:

await page.evaluate( () => document.getElementById("inputID").value = "")

然而,有时仅操纵给定字段可能还不够(目标页面可以是具有事件侦听器的 SPA),因此最好模拟真实的按键操作。以下示例来自 puppeteer Github 中有关此任务的 the informative issue

在这里,我们按 Backspace 的次数与该字段中的字符数相同:

const inputValue = await page.$eval('#inputID', el => el.value);
for (let i = 0; i < inputValue.length; i++) {
  await page.keyboard.press('Backspace');
}

另一个有趣的解决方案是点击目标字段 3 次,这样浏览器就会 select 其中的所有文本,然后您就可以输入您想要的内容了:

const input = await page.$('#inputID');
await input.click({ clickCount: 3 })
await input.type("Blah");

您可以使用 page.keyboard methods to change input values, or you can use page.evaluate().

替换所有文本:

// Using page.keyboard:

await page.focus('#example');
await page.keyboard.down('Control');
await page.keyboard.press('A');
await page.keyboard.up('Control');
await page.keyboard.press('Backspace');
await page.keyboard.type('foo');

// Using page.evaluate:

await page.evaluate(() => {
  const example = document.getElementById('example');
  example.value = 'foo';
});

追加文字:

// Using page.keyboard:

await page.focus('#example');
await page.keyboard.press('End');
await page.keyboard.type(' bar qux');

// Using page.evaluate:

await page.evaluate(() => {
  const example = document.getElementById('example');
  example.value += ' bar qux';
});

退格最后一个字符:

// Using page.keyboard:

await page.focus('#example');
await page.keyboard.press('End');
await page.keyboard.press('Backspace');

// Using page.evaluate:

await page.evaluate(() => {
  const example = document.getElementById('example');
  example.value = example.value.slice(0, -1);
});

删除第一个字符:

// Using page.keyboard:

await page.focus('#example');
await page.keyboard.press('Home');
await page.keyboard.press('Delete');

// Using page.evaluate:

await page.evaluate(() => {
  const example = document.getElementById('example');
  example.value = example.value.slice(1);
});

如果您对模拟任何按键事件不感兴趣,您也可以使用 puppeteer 的 page.$eval 方法作为删除文本区域值的简洁方法...

await page.$eval('#inputID', el => el.value = '');
await page.type('#inputID', 'blah');

...甚至一步完全替换值,无需模拟后续输入:

await page.$eval('#inputID', el => el.value = 'blah');

嗯,您想要删除现有文本的原因通常可能是想要替换它。

您可以使用page.evalute

let title = getTitle()
let selector = getSelector()

await page.evaluate(
  ({selector, title}) => {
    let el = document.querySelector(selector)
    if ('value' in el) el.value = title
    else el.innerText = title
  },
  {selector, title}
)

以上答案存在 ESLint 问题。 以下解决方案通过了 ESLint 验证:

await page.evaluate(
  (selector) => { (document.querySelector(selector).value = ''); },
  inputBoxSelector,
);

someField.type("");

在输入您的内容之前传递空字符串。

这对我有用。

使用模拟击键的Keyboard API:

await page.focus(css);            // CSS selector of the input element
await page.keyboard.down('Shift'); 
await page.keyboard.press('Home');
await page.keyboard.up('Shift');  // Release the pressed 'Shift' key
await page.keyboard.press('Backspace');

此击键是跨平台的,而不是使用 ctrl + A(不适用于 Mac 到 select 输入字段中的所有字符)

这非常适合“仅清除”方法:

const input = await page.$('#inputID');
await input.click({ clickCount: 3 })
await page.keyboard.press('Backspace')

对我来说最干净的方法是:

  • 设置
const clearInput = async (page, { selector }) => {
  const input = await page.$(selector)
  await input.click({ clickCount: 3 })
  await page.keyboard.press('Backspace')
}
  • 用法
const page = await context.newPage()

await clearInput(page, { selector: 'input[name="session[username_or_email]"]' })
await clearInput(page, { selector: 'input[name="session[password]"]' })