如何使用 Puppeteer 从输入中删除现有文本?
Posted
技术标签:
【中文标题】如何使用 Puppeteer 从输入中删除现有文本?【英文标题】:How to delete existing text from input using Puppeteer? 【发布时间】:2019-03-08 22:06:39 【问题描述】:我正在尝试在包含当前记录标题的可编辑输入中测试修改文本 - 我希望能够测试编辑此类文本,并将其替换为其他内容。
我知道我可以使用await page.type('#inputID', 'blah');
将“blah”插入文本框(在我的情况下,现有文本仅附加“blah”),但是,我找不到任何允许删除的页面方法1或替换现有文本。
【问题讨论】:
How to clear an item value in puppeteer的可能重复 【参考方案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 次,以便浏览器选择其中的所有文本,然后您可以输入您想要的内容:
const input = await page.$('#inputID');
await input.click( clickCount: 3 )
await input.type("Blah");
【讨论】:
await input.click( clickCount: 3 ) ,这很有趣!就像我们使用浏览器一样! 请注意,三次点击解决方案不适用于包含多行的文本区域,因为它只会突出显示一个。 @vsync 2 次点击选择一个单词,3 次点击选择输入中的所有文本,这就是问题所在:) Backspace 的想法很好,但现在(Puppeteer 2)它必须是await page.keyboard.press('Backspace');
而不是 await page.press('Backspace');
await input.click( clickCount: 4 )
用于多行选择【参考方案2】:
您可以使用page.keyboard
方法更改输入值,也可以使用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);
);
【讨论】:
Mac 对应的 Windows Control + A 是 Command + A。 对于跨平台键盘解决方案,您可以改为使用page.keyboard.down('Shift')
、page.keyboard.press('End')
,然后是page.keyboard.press('Backspace')
替换所有文本不适用于 Mac,因为在 Mac 中 ctrl + A keystroke 不会选择整个文本,而是将光标放在字段的开头【参考方案3】:
如果您对模拟任何关键事件不感兴趣,您还可以使用 puppeteer 的 page.$eval 方法作为删除文本区域值的简洁方法...
await page.$eval('#inputID', el => el.value = '');
await page.type('#inputID', 'blah');
...甚至一步完全替换值,无需模拟后续输入:
await page.$eval('#inputID', el => el.value = 'blah');
【讨论】:
【参考方案4】:这非常适合“仅清除”方法:
const input = await page.$('#inputID');
await input.click( clickCount: 3 )
await page.keyboard.press('Backspace')
【讨论】:
【参考方案5】:以上答案存在 ESLint 问题。 以下通过 ESLint 验证的解决方案:
await page.evaluate(
(selector) => (document.querySelector(selector).value = ''); ,
inputBoxSelector,
);
【讨论】:
【参考方案6】:好吧,您想要删除现有文本的原因通常可能是想要替换它。
您可以使用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
)
【讨论】:
【参考方案7】:someField.type("");
在输入内容之前传递空字符串。
这对我有用。
【讨论】:
【参考方案8】:使用模拟击键的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 中不能选择输入字段中的所有字符)
【讨论】:
【参考方案9】:对我来说最干净的方式是:
设置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]"]' )
【讨论】:
以上是关于如何使用 Puppeteer 从输入中删除现有文本?的主要内容,如果未能解决你的问题,请参考以下文章
使用 Puppeteer 如何从目录上传随机文件并将其删除?