ScreenshotNeo

BlogGuides

Puppeteer Keypress Options Explained

Learn when to use Puppeteer’s press(), type(), down(), up(), and sendCharacter(), what their options do, and how to troubleshoot keyboard input.

By the ScreenshotNeo team4 October 20266 min read

Puppeteer has several keyboard methods for different jobs: use page.keyboard.type(text, options) to enter a string, page.keyboard.press(key, options) to press a named or special key, and down() followed by up() when a key must stay held across actions. press() accepts text, delay, and commands; type() accepts delay. The right choice depends on the events your page needs to receive.

1. Run a complete keyboard example

This runnable Node.js example launches Chromium, types into a focused input, presses Enter, and closes the browser. Install Puppeteer with npm install puppeteer, save the code as keyboard.mjs, then run node keyboard.mjs.

import puppeteer from 'puppeteer';

const browser = await puppeteer.launch({ headless: true });
try {
  const page = await browser.newPage();
  await page.setContent('<input id="query">');
  await page.locator('#query').click();
  await page.keyboard.type('Puppeteer keyboard');
  await page.keyboard.press('Enter');
  console.log(await page.locator('#query').map(input => input.value).wait());
} finally {
  await browser.close();
}

The example uses the current locator API to focus the input before sending keys. Keyboard events go to the focused page element, so focus the intended target before calling the keyboard methods. For the complete API details, see Puppeteer’s Keyboard class, press(), type(), and KeyInput references.

2. Choose the right keyboard method

Task Method Behavior
Enter ordinary text keyboard.type(text, options) Sends a keyboard event sequence for each character. A held modifier such as Shift does not transform the string.
Press a named or special key keyboard.press(key, options) A shortcut for down() followed by up().
Keep a key held across actions keyboard.down(key), then keyboard.up(key) Use for modifiers and interactions such as selecting text while moving with an arrow key.
Send character input without keydown or keyup keyboard.sendCharacter(char) Dispatches keypress and input events only.

For example, type a phrase and then use named keys to edit it:

await page.keyboard.type('Hello');
await page.keyboard.press('ArrowLeft');
await page.keyboard.press('Backspace');

3. Understand press() options

The signature is page.keyboard.press(key, options?). The key is a Puppeteer KeyInput, such as 'Enter', 'ArrowLeft', 'Control', or 'KeyA'. Consult the official KeyInput reference for the complete accepted key list; key names are not all ordinary text characters.

Option Meaning Example
text When specified, generates an input event with this text. { text: 'x' }
delay Waits between keydown and keyup, in milliseconds. Defaults to 0. { delay: 100 }
commands Specifies keyboard shortcut command names documented by Chromium. { commands: ['selectAll'] }

The valid command names are defined by Chromium; check the Puppeteer press() reference and its linked Chromium source rather than assuming a command spelling. The text option is useful when a key press should force text input. It does not turn press() into the general-purpose string method: use type() for a string of characters.

await page.keyboard.press('Enter', { delay: 100 });
await page.keyboard.press('KeyA', { text: 'a' });

If a modifier is already held, modifiers affect press(). For example, holding Shift while pressing a letter can produce uppercase input. press() itself is still a down-and-up pair; use separate down() and up() calls when the modifier needs to remain held for multiple actions.

4. Type strings and control typing delay

keyboard.type(text, { delay }) types each character through the keyboard event sequence. Its delay defaults to zero. The delay for type() is documented as time between key presses; for press(), it is the wait between keydown and keyup. These settings describe different timing points.

await page.keyboard.type('World', { delay: 100 });
await page.keyboard.type('Done');

A held Shift key does not capitalize text sent with type(). If you need modifier-sensitive keyboard behavior, use down() and press() for those key events, or provide the desired string directly to type().

5. Hold and release keys

down(key) dispatches keydown and leaves the key held. Calling down() again for an already-held key sets repeat. Call up(key) to release it. Modifier state stays active for later key presses until released.

await page.keyboard.type('Hello World!');
await page.keyboard.press('ArrowLeft');
await page.keyboard.down('Shift');
for (let i = 0; i < ' World'.length; i++) {
  await page.keyboard.press('ArrowLeft');
}
await page.keyboard.up('Shift');
await page.keyboard.press('Backspace');

This follows the official class example: hold Shift while moving the cursor left to select text, release Shift, then delete the selection. If an exception might occur between down() and up(), use try/finally to release the modifier so it cannot affect later actions.

await page.keyboard.down('Shift');
try {
  await page.keyboard.press('ArrowLeft');
} finally {
  await page.keyboard.up('Shift');
}

6. Use sendCharacter() for character-only input

sendCharacter(char) emits keypress and input events without keydown or keyup. It differs from press(), which combines down and up, and from type(), which sends the full per-character sequence. Choose it only when the page specifically needs character input without the keydown/keyup pair.

7. Common errors and fixes

Symptom Likely cause Fix
Text appears in the wrong field or nowhere The intended element does not have focus. Locate and focus the input before using page.keyboard; check that a dialog or frame has not taken focus.
ArrowDown or Enter does not type literal text These are named keys, not ordinary text input. Use type() for text; use press() for the key action.
Holding Shift does not uppercase a string type() ignores held modifiers when generating its text. Pass the intended capitalization to type(), or use key-by-key press() with Shift held.
Subsequent actions behave as if a modifier is active A key was pressed with down() and never released. Call up(); release held keys in a finally block.
A shortcut behaves differently than expected on macOS The Keyboard class documentation notes that macOS shortcuts such as Command+A for Select All do not work through this API. Do not assume this shortcut works through page.keyboard; consult the current Puppeteer documentation and issue reference for platform-specific status.
An option or key name is rejected or has no effect The installed Puppeteer version may differ from the API page or the key/command name may be invalid. Check the installed-version documentation and the KeyInput/Chromium command references.

Puppeteer’s API pages in the research dossier show differing version labels across methods. Verify newer options against the documentation matching your installed package version.

8. Performance and reliability notes

With no delay, type() runs without an intentional per-character wait. A nonzero delay adds time as characters are sent, so reserve it for cases where gradual keyboard events matter. Likewise, a delay on press() intentionally holds the key between keydown and keyup. Avoid adding delays as a substitute for waiting for the page to be ready: focus the correct element and wait for the application state you need before typing.

Keyboard input is event-driven. A field may update only after particular events, and special keys do not mean the same thing as inserting text. Select the method based on the event sequence the target page expects, release held keys reliably, and verify the resulting field value or application state when correctness matters. No keyboard method guarantees that a page’s own event handlers or validation will accept the input.

9. Or skip the browser setup

If your goal is a screenshot rather than keyboard interaction, ScreenshotNeo is a website screenshot API and MCP server. One GET request captures a URL as an image or PDF. See the ScreenshotNeo API documentation.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
  • Cookie banners, popups, and chat widgets are removed before the shot.
  • Bot checks, blank pages, and failed loads are never billed.
  • An MCP server lets AI agents take screenshots.
  • 1,000 screenshots a month are free with no card; paid plans start at $5 for 3,000.

Sign up free for 1,000 screenshots a month, no card required.

10. FAQ

Can I use keyboard.press() to type a sentence?

Use type() for a sentence. press() is for one named key press, with options for text input, timing, and commands.

Does keyboard.type() behave like a physical keyboard?

It sends keyboard events for each character, but it is a browser automation API and its modifier behavior is explicitly different: held modifiers do not transform text typed with type().

Where can I find every valid key name?

Use Puppeteer’s KeyInput reference, which lists accepted keys.