diff --git a/docs/src/api/class-keyboard.md b/docs/src/api/class-keyboard.md index 77c561ce3c8c2..0bcaf6a59f96a 100644 --- a/docs/src/api/class-keyboard.md +++ b/docs/src/api/class-keyboard.md @@ -308,8 +308,6 @@ In most cases, you should use [`method: Locator.fill`] instead. You only need to Sends a `keydown`, `keypress`/`input`, and `keyup` event for each character in the text. -When [`option: namedKeys`] is `true`, anything inside `{}` is treated as a key name (same format as [`method: Keyboard.press`]). - To press a special key, like `Control` or `ArrowDown`, use [`method: Keyboard.press`]. **Usage** @@ -317,9 +315,6 @@ To press a special key, like `Control` or `ArrowDown`, use [`method: Keyboard.pr ```js await page.keyboard.type('Hello'); // Types instantly await page.keyboard.type('World', { delay: 100 }); // Types slower, like a user - -// Mix text and special keys -await page.keyboard.type('Hello{Enter}World', { namedKeys: true }); ``` ```java @@ -327,33 +322,21 @@ await page.keyboard.type('Hello{Enter}World', { namedKeys: true }); page.keyboard().type("Hello"); // Types slower, like a user page.keyboard().type("World", new Keyboard.TypeOptions().setDelay(100)); - -// Mix text and special keys -page.keyboard().type("Hello{Enter}World", new Keyboard.TypeOptions().setNamedKeys(true)); ``` ```python async await page.keyboard.type("Hello") # types instantly await page.keyboard.type("World", delay=100) # types slower, like a user - -# Mix text and special keys -await page.keyboard.type("Hello{Enter}World", named_keys=True) ``` ```python sync page.keyboard.type("Hello") # types instantly page.keyboard.type("World", delay=100) # types slower, like a user - -# Mix text and special keys -page.keyboard.type("Hello{Enter}World", named_keys=True) ``` ```csharp await page.Keyboard.TypeAsync("Hello"); // types instantly await page.Keyboard.TypeAsync("World", new() { Delay = 100 }); // types slower, like a user - -// Mix text and special keys -await page.Keyboard.TypeAsync("Hello{Enter}World", new() { NamedKeys = true }); ``` :::note @@ -376,13 +359,6 @@ A text to type into a focused element. Time to wait between key presses in milliseconds. Defaults to 0. -### option: Keyboard.type.namedKeys -* since: v1.61 -- `namedKeys` <[boolean]> - -When [`option: namedKeys`] is `true`, anything inside `{}` is treated as a key name (same format as [`method: Keyboard.press`]). -Use `{{` to type a literal brace character. Defaults to `false`. - ## async method: Keyboard.up * since: v1.8 diff --git a/docs/src/api/class-locator.md b/docs/src/api/class-locator.md index f2004c3318988..59a98671aec5e 100644 --- a/docs/src/api/class-locator.md +++ b/docs/src/api/class-locator.md @@ -2103,8 +2103,6 @@ In most cases, you should use [`method: Locator.fill`] instead. You only need to Focuses the element, and then sends a `keydown`, `keypress`/`input`, and `keyup` event for each character in the text. -When [`option: namedKeys`] is `true`, anything inside `{}` is treated as a key name (same format as [`method: Locator.press`]). - To press a special key, like `Control` or `ArrowDown`, use [`method: Locator.press`]. **Usage** @@ -2112,43 +2110,26 @@ To press a special key, like `Control` or `ArrowDown`, use [`method: Locator.pre ```js await locator.pressSequentially('Hello'); // Types instantly await locator.pressSequentially('World', { delay: 100 }); // Types slower, like a user - -// Mix characters and named keys -await locator.pressSequentially('Hello{Enter}World', { namedKeys: true }); -// Use modifier combos -await locator.pressSequentially('{Control+A}{Delete}Hello', { namedKeys: true }); ``` ```java locator.pressSequentially("Hello"); // Types instantly locator.pressSequentially("World", new Locator.pressSequentiallyOptions().setDelay(100)); // Types slower, like a user - -// Mix characters and named keys -locator.pressSequentially("Hello{Enter}World", new Locator.pressSequentiallyOptions().setNamedKeys(true)); ``` ```python async await locator.press_sequentially("hello") # types instantly await locator.press_sequentially("world", delay=100) # types slower, like a user - -# Mix characters and named keys -await locator.press_sequentially("Hello{Enter}World", named_keys=True) ``` ```python sync locator.press_sequentially("hello") # types instantly locator.press_sequentially("world", delay=100) # types slower, like a user - -# Mix characters and named keys -locator.press_sequentially("Hello{Enter}World", named_keys=True) ``` ```csharp await locator.PressSequentiallyAsync("Hello"); // Types instantly await locator.PressSequentiallyAsync("World", new() { Delay = 100 }); // Types slower, like a user - -// Mix characters and named keys -await locator.PressSequentiallyAsync("Hello{Enter}World", new() { NamedKeys = true }); ``` An example of typing into a text field and then submitting the form: @@ -2187,7 +2168,7 @@ await locator.PressAsync("Enter"); * since: v1.38 - `text` <[string]> -String of characters to sequentially press into a focused element. When [`option: namedKeys`] is `true`, anything inside `{}` is treated as a key name (same format as [`method: Locator.press`]). +String of characters to sequentially press into a focused element. ### option: Locator.pressSequentially.delay * since: v1.38 @@ -2195,13 +2176,6 @@ String of characters to sequentially press into a focused element. When [`option Time to wait between key presses in milliseconds. Defaults to 0. -### option: Locator.pressSequentially.namedKeys -* since: v1.61 -- `namedKeys` <[boolean]> - -When [`option: namedKeys`] is `true`, anything inside `{}` is treated as a key name (same format as [`method: Locator.press`]). -Use `{{` to type a literal brace character. Defaults to `false`. - ### option: Locator.pressSequentially.noWaitAfter = %%-input-no-wait-after-removed-%% * since: v1.38 diff --git a/packages/playwright-client/types/types.d.ts b/packages/playwright-client/types/types.d.ts index f03a833351206..8d65a2bb6086f 100644 --- a/packages/playwright-client/types/types.d.ts +++ b/packages/playwright-client/types/types.d.ts @@ -14731,10 +14731,6 @@ export interface Locator { * Focuses the element, and then sends a `keydown`, `keypress`/`input`, and `keyup` event for each character in the * text. * - * When [`namedKeys`](https://playwright.dev/docs/api/class-locator#locator-press-sequentially-option-named-keys) is - * `true`, anything inside `{}` is treated as a key name (same format as - * [locator.press(key[, options])](https://playwright.dev/docs/api/class-locator#locator-press)). - * * To press a special key, like `Control` or `ArrowDown`, use * [locator.press(key[, options])](https://playwright.dev/docs/api/class-locator#locator-press). * @@ -14743,11 +14739,6 @@ export interface Locator { * ```js * await locator.pressSequentially('Hello'); // Types instantly * await locator.pressSequentially('World', { delay: 100 }); // Types slower, like a user - * - * // Mix characters and named keys - * await locator.pressSequentially('Hello{Enter}World', { namedKeys: true }); - * // Use modifier combos - * await locator.pressSequentially('{Control+A}{Delete}Hello', { namedKeys: true }); * ``` * * An example of typing into a text field and then submitting the form: @@ -14758,10 +14749,7 @@ export interface Locator { * await locator.press('Enter'); * ``` * - * @param text String of characters to sequentially press into a focused element. When - * [`namedKeys`](https://playwright.dev/docs/api/class-locator#locator-press-sequentially-option-named-keys) is - * `true`, anything inside `{}` is treated as a key name (same format as - * [locator.press(key[, options])](https://playwright.dev/docs/api/class-locator#locator-press)). + * @param text String of characters to sequentially press into a focused element. * @param options */ pressSequentially(text: string, options?: { @@ -14770,14 +14758,6 @@ export interface Locator { */ delay?: number; - /** - * When [`namedKeys`](https://playwright.dev/docs/api/class-locator#locator-press-sequentially-option-named-keys) is - * `true`, anything inside `{}` is treated as a key name (same format as - * [locator.press(key[, options])](https://playwright.dev/docs/api/class-locator#locator-press)). Use `{{` to type a - * literal brace character. Defaults to `false`. - */ - namedKeys?: boolean; - /** * This option has no effect. * @deprecated This option has no effect. @@ -19963,10 +19943,6 @@ export interface Keyboard { * * Sends a `keydown`, `keypress`/`input`, and `keyup` event for each character in the text. * - * When [`namedKeys`](https://playwright.dev/docs/api/class-keyboard#keyboard-type-option-named-keys) is `true`, - * anything inside `{}` is treated as a key name (same format as - * [keyboard.press(key[, options])](https://playwright.dev/docs/api/class-keyboard#keyboard-press)). - * * To press a special key, like `Control` or `ArrowDown`, use * [keyboard.press(key[, options])](https://playwright.dev/docs/api/class-keyboard#keyboard-press). * @@ -19975,9 +19951,6 @@ export interface Keyboard { * ```js * await page.keyboard.type('Hello'); // Types instantly * await page.keyboard.type('World', { delay: 100 }); // Types slower, like a user - * - * // Mix text and special keys - * await page.keyboard.type('Hello{Enter}World', { namedKeys: true }); * ``` * * **NOTE** Modifier keys DO NOT effect `keyboard.type`. Holding down `Shift` will not type the text in upper case. @@ -19992,14 +19965,6 @@ export interface Keyboard { * Time to wait between key presses in milliseconds. Defaults to 0. */ delay?: number; - - /** - * When [`namedKeys`](https://playwright.dev/docs/api/class-keyboard#keyboard-type-option-named-keys) is `true`, - * anything inside `{}` is treated as a key name (same format as - * [keyboard.press(key[, options])](https://playwright.dev/docs/api/class-keyboard#keyboard-press)). Use `{{` to type - * a literal brace character. Defaults to `false`. - */ - namedKeys?: boolean; }): Promise; /** diff --git a/packages/playwright-core/src/protocol/validator.ts b/packages/playwright-core/src/protocol/validator.ts index 523e59a669eb2..4a9b428e56fc3 100644 --- a/packages/playwright-core/src/protocol/validator.ts +++ b/packages/playwright-core/src/protocol/validator.ts @@ -1605,7 +1605,6 @@ scheme.FrameTypeParams = tObject({ strict: tOptional(tBoolean), text: tString, delay: tOptional(tFloat), - namedKeys: tOptional(tBoolean), timeout: tFloat, }); scheme.FrameTypeResult = tOptional(tObject({})); @@ -2491,7 +2490,6 @@ scheme.PageKeyboardInsertTextResult = tOptional(tObject({})); scheme.PageKeyboardTypeParams = tObject({ text: tString, delay: tOptional(tFloat), - namedKeys: tOptional(tBoolean), }); scheme.PageKeyboardTypeResult = tOptional(tObject({})); scheme.PageKeyboardPressParams = tObject({ diff --git a/packages/playwright-core/src/server/dom.ts b/packages/playwright-core/src/server/dom.ts index 4ff97881ebb74..3624a05691a3c 100644 --- a/packages/playwright-core/src/server/dom.ts +++ b/packages/playwright-core/src/server/dom.ts @@ -774,13 +774,13 @@ export class ElementHandle extends js.JSHandle { return await progress.race(this.evaluateInUtility(([injected, node]) => injected.blurNode(node), {})); } - async type(progress: Progress, text: string, options: { delay?: number, namedKeys?: boolean } & types.StrictOptions): Promise { + async type(progress: Progress, text: string, options: { delay?: number } & types.StrictOptions): Promise { await this._markAsTargetElement(progress); const result = await this._type(progress, text, options); return assertDone(throwRetargetableDOMError(result)); } - async _type(progress: Progress, text: string, options: { delay?: number, namedKeys?: boolean } & types.StrictOptions): Promise<'error:notconnected' | 'done'> { + async _type(progress: Progress, text: string, options: { delay?: number } & types.StrictOptions): Promise<'error:notconnected' | 'done'> { progress.log(`elementHandle.type("${text}")`); await progress.race(this.instrumentation.onBeforeInputAction(this, progress.metadata)); const result = await this._focus(progress, true /* resetSelectionIfNotFocused */); diff --git a/packages/playwright-core/src/server/frames.ts b/packages/playwright-core/src/server/frames.ts index 48a352bcc1f17..31fdaca340b9e 100644 --- a/packages/playwright-core/src/server/frames.ts +++ b/packages/playwright-core/src/server/frames.ts @@ -1470,7 +1470,7 @@ export class Frame extends SdkObject { dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options, (progress, handle) => handle._drop(progress, inputFileItems, data, options))); } - async type(progress: Progress, selector: string, text: string, options: { delay?: number, namedKeys?: boolean, noAutoWaiting?: boolean } & types.StrictOptions) { + async type(progress: Progress, selector: string, text: string, options: { delay?: number, noAutoWaiting?: boolean } & types.StrictOptions) { return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options, (progress, handle) => handle._type(progress, text, options))); } diff --git a/packages/playwright-core/src/server/input.ts b/packages/playwright-core/src/server/input.ts index cd69223d0d260..74bde697bf812 100644 --- a/packages/playwright-core/src/server/input.ts +++ b/packages/playwright-core/src/server/input.ts @@ -103,24 +103,20 @@ export class Keyboard { await this._raw.sendText(progress, text); } - async apiType(progress: Progress, text: string, options?: { delay?: number, namedKeys?: boolean }) { + async apiType(progress: Progress, text: string, options?: { delay?: number }) { await progress.race(this._page.instrumentation.onBeforeInputAction(this._page, progress.metadata)); await this.type(progress, text, options); } - async type(progress: Progress, text: string, options?: { delay?: number, namedKeys?: boolean }) { + async type(progress: Progress, text: string, options?: { delay?: number }) { const delay = (options && options.delay) || undefined; - for (const token of parseNamedKeys(text, !!options?.namedKeys)) { - if (token.type === 'key') { - await this.press(progress, token.value, { delay }); + for (const char of text) { + if (usKeyboardLayout.has(char)) { + await this.press(progress, char, { delay }); } else { - if (usKeyboardLayout.has(token.value)) { - await this.press(progress, token.value, { delay }); - } else { - if (delay) - await progress.wait(delay); - await this.insertText(progress, token.value); - } + if (delay) + await progress.wait(delay); + await this.insertText(progress, char); } } } @@ -358,34 +354,6 @@ function buildLayoutClosure(layout: keyboardLayout.KeyboardLayout): Map { - if (!namedKeys) - return [...text].map(value => ({ type: 'char' as const, value })); - const result: Array<{ type: 'key' | 'char', value: string }> = []; - let i = 0; - while (i < text.length) { - if (text[i] === '{') { - if (i + 1 < text.length && text[i + 1] === '{') { - result.push({ type: 'char', value: '{' }); - i += 2; - } else { - const end = text.indexOf('}', i + 1); - if (end === -1) { - result.push({ type: 'char', value: '{' }); - i += 1; - } else { - result.push({ type: 'key', value: text.substring(i + 1, end) }); - i = end + 1; - } - } - } else { - result.push({ type: 'char', value: text[i] }); - i += 1; - } - } - return result; -} - export interface RawTouchscreen { tap(progress: Progress, x: number, y: number, modifiers: Set): Promise; } diff --git a/packages/playwright-core/types/types.d.ts b/packages/playwright-core/types/types.d.ts index f03a833351206..8d65a2bb6086f 100644 --- a/packages/playwright-core/types/types.d.ts +++ b/packages/playwright-core/types/types.d.ts @@ -14731,10 +14731,6 @@ export interface Locator { * Focuses the element, and then sends a `keydown`, `keypress`/`input`, and `keyup` event for each character in the * text. * - * When [`namedKeys`](https://playwright.dev/docs/api/class-locator#locator-press-sequentially-option-named-keys) is - * `true`, anything inside `{}` is treated as a key name (same format as - * [locator.press(key[, options])](https://playwright.dev/docs/api/class-locator#locator-press)). - * * To press a special key, like `Control` or `ArrowDown`, use * [locator.press(key[, options])](https://playwright.dev/docs/api/class-locator#locator-press). * @@ -14743,11 +14739,6 @@ export interface Locator { * ```js * await locator.pressSequentially('Hello'); // Types instantly * await locator.pressSequentially('World', { delay: 100 }); // Types slower, like a user - * - * // Mix characters and named keys - * await locator.pressSequentially('Hello{Enter}World', { namedKeys: true }); - * // Use modifier combos - * await locator.pressSequentially('{Control+A}{Delete}Hello', { namedKeys: true }); * ``` * * An example of typing into a text field and then submitting the form: @@ -14758,10 +14749,7 @@ export interface Locator { * await locator.press('Enter'); * ``` * - * @param text String of characters to sequentially press into a focused element. When - * [`namedKeys`](https://playwright.dev/docs/api/class-locator#locator-press-sequentially-option-named-keys) is - * `true`, anything inside `{}` is treated as a key name (same format as - * [locator.press(key[, options])](https://playwright.dev/docs/api/class-locator#locator-press)). + * @param text String of characters to sequentially press into a focused element. * @param options */ pressSequentially(text: string, options?: { @@ -14770,14 +14758,6 @@ export interface Locator { */ delay?: number; - /** - * When [`namedKeys`](https://playwright.dev/docs/api/class-locator#locator-press-sequentially-option-named-keys) is - * `true`, anything inside `{}` is treated as a key name (same format as - * [locator.press(key[, options])](https://playwright.dev/docs/api/class-locator#locator-press)). Use `{{` to type a - * literal brace character. Defaults to `false`. - */ - namedKeys?: boolean; - /** * This option has no effect. * @deprecated This option has no effect. @@ -19963,10 +19943,6 @@ export interface Keyboard { * * Sends a `keydown`, `keypress`/`input`, and `keyup` event for each character in the text. * - * When [`namedKeys`](https://playwright.dev/docs/api/class-keyboard#keyboard-type-option-named-keys) is `true`, - * anything inside `{}` is treated as a key name (same format as - * [keyboard.press(key[, options])](https://playwright.dev/docs/api/class-keyboard#keyboard-press)). - * * To press a special key, like `Control` or `ArrowDown`, use * [keyboard.press(key[, options])](https://playwright.dev/docs/api/class-keyboard#keyboard-press). * @@ -19975,9 +19951,6 @@ export interface Keyboard { * ```js * await page.keyboard.type('Hello'); // Types instantly * await page.keyboard.type('World', { delay: 100 }); // Types slower, like a user - * - * // Mix text and special keys - * await page.keyboard.type('Hello{Enter}World', { namedKeys: true }); * ``` * * **NOTE** Modifier keys DO NOT effect `keyboard.type`. Holding down `Shift` will not type the text in upper case. @@ -19992,14 +19965,6 @@ export interface Keyboard { * Time to wait between key presses in milliseconds. Defaults to 0. */ delay?: number; - - /** - * When [`namedKeys`](https://playwright.dev/docs/api/class-keyboard#keyboard-type-option-named-keys) is `true`, - * anything inside `{}` is treated as a key name (same format as - * [keyboard.press(key[, options])](https://playwright.dev/docs/api/class-keyboard#keyboard-press)). Use `{{` to type - * a literal brace character. Defaults to `false`. - */ - namedKeys?: boolean; }): Promise; /** diff --git a/packages/protocol/spec/frame.yml b/packages/protocol/spec/frame.yml index a2ca0bfd7103b..706f1d810a560 100644 --- a/packages/protocol/spec/frame.yml +++ b/packages/protocol/spec/frame.yml @@ -681,7 +681,6 @@ Frame: strict: boolean? text: string delay: float? - namedKeys: boolean? timeout: float flags: slowMo: true diff --git a/packages/protocol/spec/page.yml b/packages/protocol/spec/page.yml index 900dc11b5763e..045373af56c4a 100644 --- a/packages/protocol/spec/page.yml +++ b/packages/protocol/spec/page.yml @@ -305,7 +305,6 @@ Page: parameters: text: string delay: float? - namedKeys: boolean? flags: slowMo: true snapshot: true diff --git a/packages/protocol/src/channels.d.ts b/packages/protocol/src/channels.d.ts index 9a19765c00ecb..1f2dc53eb1efe 100644 --- a/packages/protocol/src/channels.d.ts +++ b/packages/protocol/src/channels.d.ts @@ -2941,13 +2941,11 @@ export type FrameTypeParams = { strict?: boolean, text: string, delay?: number, - namedKeys?: boolean, timeout: number, }; export type FrameTypeOptions = { strict?: boolean, delay?: number, - namedKeys?: boolean, }; export type FrameTypeResult = void; export type FrameUncheckParams = { @@ -4428,11 +4426,9 @@ export type PageKeyboardInsertTextResult = void; export type PageKeyboardTypeParams = { text: string, delay?: number, - namedKeys?: boolean, }; export type PageKeyboardTypeOptions = { delay?: number, - namedKeys?: boolean, }; export type PageKeyboardTypeResult = void; export type PageKeyboardPressParams = { diff --git a/tests/page/page-keyboard.spec.ts b/tests/page/page-keyboard.spec.ts index 8d29c64c96c57..391e2c042e93b 100644 --- a/tests/page/page-keyboard.spec.ts +++ b/tests/page/page-keyboard.spec.ts @@ -787,19 +787,3 @@ it('should close dialog on Escape key press in contenteditable', { await expect(dialog).toHaveJSProperty('open', false); await expect(widget).not.toBeVisible(); }); - -it('should type with namedKeys', async ({ page }) => { - await page.evaluate(() => { - const textarea = document.createElement('textarea'); - document.body.appendChild(textarea); - textarea.focus(); - }); - await page.keyboard.type('He{{ll}o{Enter}Wor{ld', { namedKeys: true }); - expect(await page.evaluate(() => document.querySelector('textarea')!.value)).toBe('He{ll}o\nWor{ld'); -}); - -it('locator should pressSequentially with namedKeys', async ({ page }) => { - await page.setContent(``); - await page.locator('textarea').pressSequentially('Hello{Enter}World', { namedKeys: true }); - expect(await page.$eval('textarea', el => el.value)).toBe('Hello\nWorld'); -});