首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使用Puppeteer粘贴文本?

如何使用Puppeteer粘贴文本?
EN

Stack Overflow用户
提问于 2019-07-19 03:28:41
回答 2查看 6.8K关注 0票数 9

我正在尝试为我的React应用程序中的输入编写一个测试(使用jest-puppeteer),它以一种独特的方式处理自动完成或复制/粘贴的字符串。

我希望通过使用Puppeteer,我可以将文本粘贴到输入中,然后验证页面是否正确更新。不幸的是,我找不到任何可行的例子来说明如何做到这一点。

我曾尝试使用page.keyboard来模拟CMD+CCMD+V,但似乎这类命令在Puppeteer中不起作用。

我还尝试使用诸如clipboardy之类的库来写入和读取操作系统剪贴板。虽然clipboardy确实适用于写入(复制),但读取(粘贴)似乎不会影响Puppeteer运行的页面。

我已经使用各种方法成功地复制了文本,但无法粘贴到输入中。我已经通过在文档中添加"copy""paste"的事件侦听器验证了这一假设。激发"copy"事件,但没有任何方法导致激发"paste"事件。

以下是我尝试过的几种方法:

代码语言:javascript
运行
复制
await clipboardy.write('1234'); // writes "1234" to clipboard
await page.focus("input");
await clipboardy.read(); // Supposedly pastes from clipboard
// assert input has updated
代码语言:javascript
运行
复制
await clipboardy.write('1234');
await page.focus("input");
await page.keyboard.down('Meta');
await page.keyboard.press('KeyV');
await page.keyboard.up('Meta');
// assert input has updated
代码语言:javascript
运行
复制
await page.evaluate(() => {
  const input = document.createElement('input');
  document.body.appendChild(input);
  input.value = '1234';
  input.focus();
  input.select();
  document.execCommand('copy');
  document.body.removeChild(input);
});
wait page.focus("input");
await page.keyboard.down('Meta');
await page.keyboard.press('KeyV');
await page.keyboard.up('Meta');

我认为这里唯一缺少的部分是粘贴文本;但是如何使用Puppeteer粘贴文本呢?

EN

回答 2

Stack Overflow用户

发布于 2019-07-26 22:19:17

这适用于我的clipboardy,但当我在headless中启动它时就不行了:

代码语言:javascript
运行
复制
await clipboardy.write('foo')

const input= await puppeteerPage.$(inputSelector)
await input.focus()

await puppeteerPage.keyboard.down('Control')
await puppeteerPage.keyboard.press('V')
await puppeteerPage.keyboard.up('Control')

如果你让它在无头模式下工作,告诉我。

我也在clipBoard API上尝试过,但是我不能编译它:

代码语言:javascript
运行
复制
const browser = await getBrowser()
const context = browser.defaultBrowserContext();
// set clipBoard API permissions
context.clearPermissionOverrides()
context.overridePermissions(config.APPLICATION_URL, ['clipboard-write'])
puppeteerPage = await browser.newPage()

await puppeteerPage.evaluate((textToCopy) =>{
  navigator.clipboard.writeText(textToCopy)
}, 'bar')

const input= await puppeteerPage.$(inputSelector)
await input.focus()

await puppeteerPage.evaluate(() =>{
  navigator.clipboard.readText()
})
票数 5
EN

Stack Overflow用户

发布于 2020-10-11 16:18:06

我想出了一个有趣的解决办法,如何将一个长文本粘贴到React组件中,这样更改将由组件注册,并且不会像通常使用type命令那样花费很长时间来输入:

对于文本复制,我使用Puppeteer文档中的方法(例如,假设我想从页面的前两个段落中选择文本)。我假设您已经知道如何设置剪贴板读取和写入的权限(例如,上面的答案之一显示了如何设置)。

代码语言:javascript
运行
复制
const fromJSHandle = await page.evaluateHandle(() =>Array.from(document.querySelectorAll('p'))[0])
const toJSHandle   = await page.evaluateHandle(() =>Array.from(document.querySelectorAll('p'))[1])

// from puppeteer docs
await page.evaluate((from, to) => {
     const selection = from.getRootNode().getSelection();
     const range = document.createRange();
     range.setStartBefore(from);
     range.setEndAfter(to);
     selection.removeAllRanges();
     selection.addRange(range);
}, fromJSHandle, toJSHandle);

await page.bringToFront();
await page.evaluate(() => {
     document.execCommand('copy') // Copy the selected content to the clipboard
     return navigator.clipboard.readText() // Obtain the content of the clipboard as a string
})

这种方法不适用于粘贴(至少在Mac上):document.execCommand('paste')

因此,对于粘贴,我使用以下命令:

代码语言:javascript
运行
复制
await page.$eval('#myInput', (el, value) =>{ el.value = value }, myLongText)
await page.type(`#myInput`,' ') // this assumes your app trims the input value in the end so the whitespace doesn't bother you

如果没有最后的输入步骤(空格),React不会注册change/input事件。因此,在提交表单(例如,输入是表单的一部分)之后,输入值仍然是"“。这就是输入空格的用武之地-它会触发change事件,我们就可以提交表单了。

似乎人们需要用Puppeteer开发出相当多的独创性,以弄清楚如何绕过所有的限制,同时保持一定程度的开发人员舒适性。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57101467

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档