Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minutePC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11To hold a key in Puppeteer, call await page.keyboard.down('ArrowLeft'), do the action that needs the key held, then call await page.keyboard.up('ArrowLeft'). Use the same key name in both calls. Wrap the intervening work in try/finally when it might fail, so the key is released even if an action throws.
Hold a key with down() and up()
Puppeteer’s virtual keyboard keeps a key pressed between the down() and up() calls. The first dispatches a keydown event; the second dispatches keyup. For example:
await page.keyboard.down('ArrowLeft');
// Do the action that should happen while ArrowLeft is held.
await page.keyboard.up('ArrowLeft');
Use this pattern when the page must respond to a key remaining held during another action, rather than just to a single press. Puppeteer’s current API method references displayed version 25.12.0 on October 3, 2026; check the documentation for the version installed in your project if behavior or accepted key names matter.
Release the key if an action fails
If work between the down and up calls can throw an error, put the dependent action in a try block and release in finally:
Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Fix the driver behind crashes, sound loss and screen glitches3Clear out junk files and repair common Windows errors#1 Best Overall
await page.keyboard.down('Shift');
try {
await page.keyboard.press('ArrowLeft');
} finally {
await page.keyboard.up('Shift');
}
This ensures the script attempts the release on both success and failure paths. Use the same key value for the matching down and up calls.
Choose the right keyboard method
| What you need | Use | Behavior |
|---|---|---|
| Keep a key held across another action | down(key), then up(key) |
Dispatches keydown, keeps the key held in Puppeteer’s keyboard state, then dispatches keyup when released. |
| Press and release once, optionally with a delay | press(key, { delay }) |
A shortcut for down and up. The optional delay is the number of milliseconds between keydown and keyup; it defaults to zero. |
| Enter ordinary text | type(text, { delay }) |
Sends text character by character. The optional delay is between key events and defaults to zero. |
| Press a key on a particular element | elementHandle.press(key) |
Focuses the element, then uses a keyboard down/up pair. |
These methods serve different purposes: press() is not a sustained hold, and type() is text entry rather than a way to send special keys such as arrows. Holding Shift does not make type() convert its text to uppercase.
Rank #2
Use modifiers and named keys
To select text while moving left, hold Shift while pressing the arrow key, release Shift, and then delete the selection:
await page.keyboard.down('Shift');
await page.keyboard.press('ArrowLeft');
await page.keyboard.up('Shift');
await page.keyboard.press('Backspace');
Puppeteer documents modifier names including Shift, Meta, Control, and Alt. A held modifier stays active for subsequent key presses until you release it with up(). The KeyInput type also includes names such as ArrowLeft, ArrowDown, Backspace, and Enter, as well as letter and digit representations. See the Puppeteer KeyInput reference for the accepted values.
For example, the API reference shows a shifted A using:
await page.keyboard.down('Shift');
await page.keyboard.press('KeyA');
await page.keyboard.up('Shift');
Keyboard input is sent to the focused page context. Focus the intended control through your normal page interaction before sending keys. If you use ElementHandle.press(), Puppeteer focuses that element first.
Rank #4
Troubleshoot key presses that do not work
- The key is not held during the later action: use
down()andup()around that action.press()releases automatically after its down/up pair. - An arrow or other special key is treated like text: use
press()or explicit down/up calls for special keys; reservetype()for text. - The wrong control reacts: make sure the intended element has focus before sending page-level keyboard input, or use
ElementHandle.press()to focus an element before pressing. - A modifier affects more keys than intended: release it with
up()after the dependent key action. Put that release infinallyif intervening code can fail. - The key name is rejected or does not behave as expected: check that the value is a documented Puppeteer
KeyInputand is spelled identically in both down and up calls. - A macOS shortcut such as Command+A does not work: Puppeteer’s current Keyboard class reference notes a limitation for keyboard shortcuts such as
⌘ Aon macOS. This caveat concerns shortcuts and should not be generalized to all keyboard actions.
Or skip the browser setup
If your goal is a screenshot rather than testing keyboard interaction, ScreenshotNeo can return a site screenshot with one GET request. Its screenshot API does not operate a browser keyboard or reproduce key holds; use Puppeteer above when a page interaction must occur before capture.
For a direct capture, replace the sample URL with the page you need and use your API key. See the ScreenshotNeo documentation for API options.
Best Value
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
ScreenshotNeo removes cookie or consent banners, newsletter popups, and chat widgets before capture; each cleanup step can be turned off. Bot checks, blank pages, failed loads, timeouts, and cache hits cost nothing, and response headers identify the page verdict and billing status. It also provides an MCP server for AI agents, with tools for screenshots, page information, and PDF capture. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots.
Sign up for ScreenshotNeo’s free plan to try it without a card.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Frequently Asked Questions
Does Puppeteer’s key hold wait for a fixed amount of time?
No. With explicit down/up calls, the key remains held until your code reaches the release call; a timed interval is only needed if your task requires one.
Can I use this pattern to hold Shift while typing uppercase text?
No. Puppeteer’s type() sends text character by character, and holding Shift does not make it uppercase. Use the appropriate text directly or send individual key actions.
Recommended Free Tools
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

