ScreenshotNeo

BlogGuides

Puppeteer Keydown Options Explained

Learn what Puppeteer’s keyboard.down() options do, when to use down(), press(), or type(), and how to handle modifiers, held keys, and common errors.

By the ScreenshotNeo team4 October 20267 min read

page.keyboard.down(key, options) dispatches a keydown and leaves the key held until you call page.keyboard.up(key). Its documented options are text, which can generate input with specified text, and commands, which carries keyboard shortcut command names. Use press() for a single press-and-release, and type() for ordinary text.

The available command names are not enumerated in the API page. Check the declarations and documentation for the Puppeteer version installed in your project before relying on a particular command.

1. Runnable setup

Install Puppeteer in a Node.js project:

npm install puppeteer

Save this as keydown.mjs and run node keydown.mjs. It opens a page, focuses an input, holds Shift while pressing a key, and releases Shift even if the action fails.

import puppeteer from 'puppeteer';

const browser = await puppeteer.launch({ headless: true });
try {
  const page = await browser.newPage();
  await page.setContent('<input id="target" value="hello">');
  await page.focus('#target');

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

  console.log(await page.$eval('#target', el => el.value));
} finally {
  await browser.close();
}

For the official API signatures and version-specific type details, see the Keyboard.down() reference, the Keyboard class reference, and the installed package’s TypeScript declarations.

2. What options does keyboard.down() accept?

The method signature is down(key, options?). The optional argument is a KeyDownOptions object. The documented properties are:

Option Purpose Practical guidance
text If specified, generates input with that text. Use only when you need to control the text associated with the keydown. For normal strings, type(text) is clearer.
commands Passes keyboard shortcut command names. The API page points to Chromium source for valid names but does not list them. Confirm availability and spelling against your installed Puppeteer version and target Chromium.

These options do not make down() release the key. A successful call leaves the key pressed; pair it with up() when the held state should end. If the same key is sent down again before release, subsequent calls set the event’s repeat state.

Using the text option

await page.keyboard.down('a', { text: 'a' });
await page.keyboard.up('a');

The text option describes generated input text; it is not a replacement for typing a complete string. For string entry, prefer type() and its optional per-character delay.

Using commands

// Shape only: supply a command name supported by your installed version.
await page.keyboard.down('某Key', { commands: ['verified-command-name'] });
await page.keyboard.up('某Key');

Replace the placeholders with a key and command valid for your version. This illustrates the option shape, not a universal command value. Do not copy an unverified command name: the reference does not provide a complete portable list.

3. Choose between down(), press(), type(), and sendCharacter()

Method Behavior Use it for
down(key, options) Dispatches keydown and keeps the key held. Repeated downs after the first set repeat. Holding a modifier or key across later keyboard actions, or controlling keydown options.
up(key) Dispatches keyup. Releasing a key previously held with down().
press(key, options) Convenience for down followed by up. Options include keydown options and a delay. A single key action such as Enter or ArrowDown, including a press-and-release.
type(text, options) Sends keydown, keypress/input, and keyup for each character. Supports a delay between characters. Entering ordinary text in the focused element.
sendCharacter(char) Sends character input without keydown or keyup. A narrow case where that event shape is specifically required.

One key press

await page.keyboard.press('ArrowDown');
await page.keyboard.press('Enter');

Hold a modifier across an action

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

The finally block matters in longer scripts: if an action throws, the modifier is still released before control leaves the block. A held modifier can otherwise affect later input and make failures difficult to diagnose.

Type text with a delay

await page.keyboard.type('Hello', { delay: 50 });

The delay is in milliseconds and defaults to zero. For press(), delay is the wait between keydown and keyup. For type(), it is the spacing between character events.

4. Modifiers and event behavior

Puppeteer documents that held modifiers affect down() and press(). For example, Shift changes the result of a key press to uppercase. Modifiers do not affect type() or sendCharacter(); holding Shift and then calling type('a') does not behave like physical Shift+A.

// Modifier participates in key press behavior.
await page.keyboard.down('Shift');
try {
  await page.keyboard.press('KeyA');
} finally {
  await page.keyboard.up('Shift');
}

// For ordinary text, send the intended character directly.
await page.keyboard.type('A');

Event listeners can observe different sequences depending on the method. If application behavior depends on a specific combination of keydown, keypress, input, or keyup events, choose the method based on that required sequence and verify it in the target page.

5. Common errors and fixes

Symptom Likely cause Fix
A modifier seems to affect later input. down() was called without a matching up(), often because an earlier operation failed. Pair the calls with try/finally so release runs on both success and error.
Typing a string does not produce the expected result. down() represents a keydown, not general string entry. Use page.keyboard.type(text) for normal text; use press() for one key.
Shift does not change keyboard.type('a'). Puppeteer documents that modifiers do not affect type(). Type the desired character directly, or use a key press if the page needs key events with a held modifier.
A shortcut command is rejected or has no effect. The command name may not exist in that Chromium/Puppeteer version, or may not apply to the key. Check the installed version’s declarations and the Chromium command definitions referenced by the API docs. Do not assume an exhaustive list from the method page.
A one-off key action remains held. down() was used where a press-and-release was intended. Use press(), or explicitly call up().
A macOS shortcut such as Command+A does not select all. The Keyboard class reference warns that shortcuts such as ⌘ A may not work on macOS. Validate the shortcut in the target environment. The cited reference flags the limitation but does not establish a general workaround.
Input goes to the wrong control or nowhere. The intended element may not have focus. Wait for the element, focus it explicitly, and confirm the page is in the expected state before sending keys.

6. Version, reliability, and performance notes

  • Check the version you run. The retrieved official API pages show different version labels across the Keyboard class and method references. Signatures and behavior can differ across releases; consult the docs and declarations for the version in your lockfile.
  • Release held keys reliably. Keep down/up pairs close together and put release calls in finally blocks when intervening work can throw.
  • Wait for the page state, not an arbitrary guess. Focus the intended element and wait for the UI condition that makes keyboard input meaningful. A correct key sequence sent too early can still produce the wrong result.
  • Use delays only when needed. A zero delay is the default and avoids adding one wait per character. Add a delay when the application requires spaced events; remember that longer per-character delays increase automation time.
  • Test shortcuts on the target platform. The official class documentation notes a macOS shortcut limitation. Do not infer that a shortcut behaves identically across operating systems.

7. Or skip the browser setup

If your task is to inspect a rendered page rather than automate keyboard interaction, ScreenshotNeo is a website screenshot API and MCP server for developers. A single GET request returns an image or PDF; the API details and its options are in the ScreenshotNeo 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}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
await import('node:fs/promises').then(fs => fs.writeFile('shot.webp', Buffer.from(await res.arrayBuffer())));
  • Cookie banners are accepted and more than 60 known consent platforms, newsletter popups, and chat widgets are removed before the shot; each step can be turned off.
  • Bot checks, blank pages, timeouts, failed loads, and cache hits cost nothing. Response headers report the page verdict and billing status.
  • An MCP server gives AI agents tools for screenshots, page information, and PDF capture.
  • The free plan includes 1,000 screenshots each month with no card. Paid plans start at $5 for 3,000 shots.

Start free with 1,000 screenshots a month and no card.

8. FAQ

Does keyboard.down() release the key automatically?

No. Call keyboard.up(key) to dispatch keyup, or use press() when you want a complete press-and-release.

Does down() support a delay option?

The documented KeyDownOptions properties are text and commands. Delay is documented for press() and type(), not as a down option.

Where can I find every valid commands value?

The method reference does not enumerate them. Follow its Chromium source reference and check the declarations and browser version used by your project.

Should I use key names such as Shift or ShiftLeft?

Use key identifiers accepted by the Puppeteer version in your project and check its Keyboard API reference. The examples in the official class documentation use Shift and KeyA.