puppeteer - 如何让 page.keyboard.press("[any key]") 使用 page.keyboard.down("Control") 调度按键事件
问题描述
重现步骤
告诉我们您的环境:
- 木偶版:v1.19.0
- 平台/操作系统版本:Windows 8.1
- 网址(如果适用):
- Node.js 版本:10.16.0
哪些步骤将重现该问题?
我有文件:
PuppeteerTest/
├── test/main.spec.js
index.html
索引.html
<textarea></textarea>
<script>
const textarea = document.querySelector("textarea");
textarea.addEventListener("keypress", e => {
const p = document.createElement("p");
p.textContent = `KeyCode: ${e.keyCode}, Ctrl Pressed: ${e.ctrlKey}, Shift Pressed: ${e.shiftKey}`
document.body.appendChild(p);
});
</script>
测试/main.spec.js
const expect = require("chai").expect;
const puppeteer = require("puppeteer");
describe("Control Key Issue", async () => {
it("Doesn't register control-modified keypresses", async () => {
const browser = await puppeteer.launch({headless: false, slowMo: 50});
const page = await browser.newPage();
await page.goto(__dirname + `/../index.html`);
const textarea = await page.$("textarea");
await textarea.focus();
await page.keyboard.down("Control"); // I've also tried ControlLeft;
await page.keyboard.press("Enter"); // I've also tried "A" and "B"
const resultingP = await page.evaluate(() => {
const p = document.querySelector("p");
if (p) {
return p.textContent;
} else {
return "No keypress event was emitted, so no <p></p>s were generated"
}
});
expect(resultingP).to.not.equal("KeyCode: 10, Ctrl Pressed: true, Shift Pressed: false");
expect(resultingP).to.equal("No keypress event was emitted, so no <p></p>s were generated");
browser.close();
}).timeout(30000);
// To prove Puppeteer works in other cases, I've made the following tests.
it("Registers non-control-modified keypresses", async () => {
const browser = await puppeteer.launch({headless: false, slowMo: 50});
const page = await browser.newPage();
await page.goto(__dirname + `/../index.html`);
const textarea = await page.$("textarea");
await textarea.focus();
await page.keyboard.press("Enter");
const resultingP = await page.evaluate(() => {
const p = document.querySelector("p");
if (p) {
return p.textContent;
} else {
return "No keypress event was emitted, so no <p></p>s were generated"
}
});
expect(resultingP).to.equal("KeyCode: 13, Ctrl Pressed: false, Shift Pressed: false");
expect(resultingP).to.not.equal("No keypress event was emitted, so no <p></p>s were generated");
browser.close();
}).timeout(30000);
it("Registers shift-modified keypresses", async () => {
const browser = await puppeteer.launch({headless: false, slowMo: 50});
const page = await browser.newPage();
await page.goto(__dirname + `/../index.html`);
const textarea = await page.$("textarea");
await textarea.focus();
await page.keyboard.down("Shift");
await page.keyboard.press("Enter");
const resultingP = await page.evaluate(() => {
const p = document.querySelector("p");
if (p) {
return p.textContent;
} else {
return "No keypress event was emitted, so no <p></p>s were generated"
}
});
expect(resultingP).to.equal("KeyCode: 13, Ctrl Pressed: false, Shift Pressed: true");
expect(resultingP).to.not.equal("No keypress event was emitted, so no <p></p>s were generated");
browser.close();
}).timeout(30000);
});
预期的结果是什么?
Control + Enter 在手动完成时会创建一个按键事件,因此我希望它会发送一个按键事件e.keyCode === 10
(或 13,但在现实世界中,Ctrl + Enter 会导致按键代码为 10)。我预计e.ctrlKey === true
。
相反会发生什么? 没有什么。当 Control 按下并按下另一个键时,不会发生任何事件。我做错了什么,还是这是一个错误?
解决方案
问题
这看起来像 puppeteer 中的错误。但请记住,keypress
事件不会在Ctrl按键上监听。引用MDN 文档:
keypress
当按下产生字符值的键时触发该事件。产生字符值的键示例有字母键、数字键和标点键。不产生字符值的键示例是修饰键,例如Alt、Shift、Ctrl或Meta。
但它至少应该在按下时触发Enter。
解决方案
对我有用的是keydown
在您的 HTML 文档中监听事件。更改将是这一行:
textarea.addEventListener("keydown", e => {
// ...
});
只需使用代码中的第一个测试(“不注册控制修改的按键”)试一试。我修改了该expect(...)
行以console.log(resultingP)
打印结果,并在控制台中返回以下内容:
KeyCode: 17, Ctrl Pressed: true, Shift Pressed: false
页面本身显示以下两行:
KeyCode: 17, Ctrl Pressed: true, Shift Pressed: false
KeyCode: 13, Ctrl Pressed: true, Shift Pressed: false
推荐阅读
- java - Kafka Join 2 Streams (Kafka 1.0.1)
- arrays - 用户 didDeselectRowAt 时删除数组元素?
- c# - JArray - 通过键名搜索对象
- arrays - 数组操作和索引
- r - R循环更改变量名称
- sql-server - MS Access 链接表到 SQL Server
- php - 电子邮件已经存在,codeigniter 中的 Jquery 验证器插件不起作用
- java - Java Spring MVC 映射问题
- angular - Angular 6:使用带有异步的日期格式管道
- flume-ng - 将水槽中的流量多路复用到多个通道中