From 2ff4f576606cde28246dc4060cabee160ba54b72 Mon Sep 17 00:00:00 2001 From: yancoding Date: Sat, 3 Dec 2022 10:48:11 +0800 Subject: [PATCH] feat(keyboard): keydown supports commands Issue: #1313 --- docs/api/puppeteer.keyboard.down.md | 9 ++++--- docs/api/puppeteer.keyboard.press.md | 9 ++++--- packages/puppeteer-core/src/common/Input.ts | 16 ++++++++--- test/TestExpectations.json | 6 +++++ test/src/keyboard.spec.ts | 30 +++++++++++++++++++++ 5 files changed, 58 insertions(+), 12 deletions(-) diff --git a/docs/api/puppeteer.keyboard.down.md b/docs/api/puppeteer.keyboard.down.md index a5d465f4e2a85..7832d1281bd55 100644 --- a/docs/api/puppeteer.keyboard.down.md +++ b/docs/api/puppeteer.keyboard.down.md @@ -14,6 +14,7 @@ class Keyboard { key: KeyInput, options?: { text?: string; + commands?: string[]; } ): Promise; } @@ -21,10 +22,10 @@ class Keyboard { ## Parameters -| Parameter | Type | Description | -| --------- | ----------------------------------- | -------------------------------------------------------------------------------------------------------------------------- | -| key | [KeyInput](./puppeteer.keyinput.md) | Name of key to press, such as ArrowLeft. See [KeyInput](./puppeteer.keyinput.md) for a list of all key names. | -| options | { text?: string; } | (Optional) An object of options. Accepts text which, if specified, generates an input event with this text. | +| Parameter | Type | Description | +| --------- | ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| key | [KeyInput](./puppeteer.keyinput.md) | Name of key to press, such as ArrowLeft. See [KeyInput](./puppeteer.keyinput.md) for a list of all key names. | +| options | { text?: string; commands?: string\[\]; } | (Optional) An object of options. Accepts text which, if specified, generates an input event with this text. Accepts commands which, if specified, is the commands of keyboard shortcuts, see [Chromium Source Code](https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/editing/commands/editor_command_names.h) for valid command names. | **Returns:** diff --git a/docs/api/puppeteer.keyboard.press.md b/docs/api/puppeteer.keyboard.press.md index 99b88b285a98f..6c685292e1768 100644 --- a/docs/api/puppeteer.keyboard.press.md +++ b/docs/api/puppeteer.keyboard.press.md @@ -15,6 +15,7 @@ class Keyboard { options?: { delay?: number; text?: string; + commands?: string[]; } ): Promise; } @@ -22,10 +23,10 @@ class Keyboard { ## Parameters -| Parameter | Type | Description | -| --------- | ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| key | [KeyInput](./puppeteer.keyinput.md) | Name of key to press, such as ArrowLeft. See [KeyInput](./puppeteer.keyinput.md) for a list of all key names. | -| options | { delay?: number; text?: string; } | (Optional) An object of options. Accepts text which, if specified, generates an input event with this text. Accepts delay which, if specified, is the time to wait between keydown and keyup in milliseconds. Defaults to 0. | +| Parameter | Type | Description | +| --------- | --------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| key | [KeyInput](./puppeteer.keyinput.md) | Name of key to press, such as ArrowLeft. See [KeyInput](./puppeteer.keyinput.md) for a list of all key names. | +| options | { delay?: number; text?: string; commands?: string\[\]; } | (Optional) An object of options. Accepts text which, if specified, generates an input event with this text. Accepts delay which, if specified, is the time to wait between keydown and keyup in milliseconds. Defaults to 0. Accepts commands which, if specified, is the commands of keyboard shortcuts, see [Chromium Source Code](https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/editing/commands/editor_command_names.h) for valid command names. | **Returns:** diff --git a/packages/puppeteer-core/src/common/Input.ts b/packages/puppeteer-core/src/common/Input.ts index 3a70708ae59e9..02ffaddf6f9ba 100644 --- a/packages/puppeteer-core/src/common/Input.ts +++ b/packages/puppeteer-core/src/common/Input.ts @@ -104,11 +104,16 @@ export class Keyboard { * See {@link KeyInput} for a list of all key names. * * @param options - An object of options. Accepts text which, if specified, - * generates an input event with this text. + * generates an input event with this text. Accepts commands which, if specified, + * is the commands of keyboard shortcuts, + * see {@link https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/editing/commands/editor_command_names.h | Chromium Source Code} for valid command names. */ async down( key: KeyInput, - options: {text?: string} = {text: undefined} + options: {text?: string; commands?: string[]} = { + text: undefined, + commands: [], + } ): Promise { const description = this.#keyDescriptionForString(key); @@ -128,6 +133,7 @@ export class Keyboard { autoRepeat, location: description.location, isKeypad: description.location === 3, + commands: options.commands, }); } @@ -304,11 +310,13 @@ export class Keyboard { * @param options - An object of options. Accepts text which, if specified, * generates an input event with this text. Accepts delay which, * if specified, is the time to wait between `keydown` and `keyup` in milliseconds. - * Defaults to 0. + * Defaults to 0. Accepts commands which, if specified, + * is the commands of keyboard shortcuts, + * see {@link https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/editing/commands/editor_command_names.h | Chromium Source Code} for valid command names. */ async press( key: KeyInput, - options: {delay?: number; text?: string} = {} + options: {delay?: number; text?: string; commands?: string[]} = {} ): Promise { const {delay = null} = options; await this.down(key, options); diff --git a/test/TestExpectations.json b/test/TestExpectations.json index cfb9d68d48f2d..22331e47605a9 100644 --- a/test/TestExpectations.json +++ b/test/TestExpectations.json @@ -569,6 +569,12 @@ "parameters": ["firefox"], "expectations": ["SKIP"] }, + { + "testIdPattern": "[keyboard.spec] Keyboard should trigger commands of keyboard shortcuts", + "platforms": ["darwin", "linux", "win32"], + "parameters": ["firefox"], + "expectations": ["SKIP"] + }, { "testIdPattern": "[keyboard.spec] Keyboard should report shiftKey", "platforms": ["darwin", "linux", "win32"], diff --git a/test/src/keyboard.spec.ts b/test/src/keyboard.spec.ts index 8627833f8b874..acad3cdf0bc19 100644 --- a/test/src/keyboard.spec.ts +++ b/test/src/keyboard.spec.ts @@ -90,6 +90,36 @@ describe('Keyboard', function () { }) ).toBe('Hello World!'); }); + // @see https://github.com/puppeteer/puppeteer/issues/1313 + it('should trigger commands of keyboard shortcuts', async () => { + const {page, server} = getTestState(); + const cmdKey = os.platform() !== 'darwin' ? 'Meta' : 'Control'; + + await page.goto(server.PREFIX + '/input/textarea.html'); + await page.type('textarea', 'hello'); + + await page.keyboard.down(cmdKey); + await page.keyboard.press('a', {commands: ['SelectAll']}); + await page.keyboard.up(cmdKey); + + await page.keyboard.down(cmdKey); + await page.keyboard.down('c', {commands: ['Copy']}); + await page.keyboard.up('c'); + await page.keyboard.up(cmdKey); + + await page.keyboard.down(cmdKey); + await page.keyboard.press('v', {commands: ['Paste']}); + await page.keyboard.up(cmdKey); + await page.keyboard.down(cmdKey); + await page.keyboard.press('v', {commands: ['Paste']}); + await page.keyboard.up(cmdKey); + + expect( + await page.evaluate(() => { + return document.querySelector('textarea')!.value; + }) + ).toBe('hellohello'); + }); it('should send a character with ElementHandle.press', async () => { const {page, server} = getTestState();