diff --git a/docs/api/puppeteer.keyboard.down.md b/docs/api/puppeteer.keyboard.down.md index a5d465f4..7832d128 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 99b88b28..6c685292 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 3a70708a..02ffaddf 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 cfb9d68d..22331e47 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 8627833f..acad3cdf 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();