首页 > 解决方案 > 如何让 page.keyboard.press("[any key]") 使用 page.keyboard.down("Control") 调度按键事件

问题描述

重现步骤

告诉我们您的环境:

哪些步骤将重现该问题?

我有文件:

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

解决方案


问题

这看起来像 puppeteer 中的错误。但请记住,keypress事件不会在Ctrl按键上监听。引用MDN 文档

keypress当按下产生字符值的键时触发该事件。产生字符值的键示例有字母键、数字键和标点键。不产生字符值的键示例是修饰键,例如AltShiftCtrlMeta

但它至少应该在按下时触发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

推荐阅读