ScreenshotNeo

BlogGuides

Cypress Keyboard Shortcuts: What’s New in cy.press()

Learn what Cypress’s cy.press() does, which keys it supports, and when to use it instead of cy.type() for keyboard navigation and focus tests.

By the ScreenshotNeo team4 October 20267 min read

cy.press() dispatches a keydown and keyup event to the browser window. Use it for individual key actions such as Tab, arrow keys, Enter, and Escape, especially when testing focus movement or keyboard navigation. Use cy.type() to enter text or send supported modifier sequences. Cypress added cy.press() in version 14.3.0; its supported keys expanded in later releases.

This guide covers the current API behavior and release history documented by Cypress. Check the official cy.press() reference when upgrading, since key support can change.

1. What cy.press() does

cy.press(key) sends a native keyboard keydown and keyup directly to the browser window. It is designed for a single key interaction, not for entering a string into an input.

The command yields null. Do not chain an assertion directly to it. Issue a subsequent Cypress command that checks the application state caused by the key.

cy.get('button').focus()
cy.press(Cypress.Keyboard.Keys.TAB)
cy.focused().should('have.attr', 'data-testid', 'next-control')

This verifies the result of pressing Tab: focus is on the expected control. Dispatching a key alone does not establish that the interface behaves correctly or accessibly.

2. What changed in cy.press()

Release Documented change
14.3.0 (April 8, 2025) Introduced cy.press(), initially for native Tab keyboard events.
15.1.0 Expanded support for named keys and single- and multi-codepoint UTF-8 characters.
15.3.0 Added {esc} key support.
15.19.0 Fixed a renderer-memory retention issue associated with repeated calls in Chromium-based browsers. This is a historical changelog entry; the source does not say the issue remains.

See the Cypress changelog for release details. The current command contract is in the API reference.

3. Which keys can cy.press() send?

The API supports individual letters, numbers, special characters, multi-codepoint UTF-8 characters, and documented named keys. Function keys F1–F12 are not supported. For named keys, prefer constants from Cypress.Keyboard.Keys where available; Cypress cautions that key values may change.

cy.press(Cypress.Keyboard.Keys.TAB)
cy.press(Cypress.Keyboard.Keys.ENTER)
cy.press(Cypress.Keyboard.Keys.ESC)
cy.press(Cypress.Keyboard.Keys.ARROWDOWN)

Use the names and values listed in the API reference for your installed Cypress version. Do not assume that a key accepted by cy.type() as part of a sequence is also accepted as a cy.press() key.

4. cy.press() vs cy.type()

Need Use Example
Move focus with Tab or exercise a single navigation key cy.press() cy.press(Cypress.Keyboard.Keys.TAB)
Enter a word, sentence, or form value cy.type() cy.get('input').type('hello')
Send a supported modifier or special-character sequence cy.type() cy.get('input').type('{ctrl}c')
Test a custom key-driven behavior, such as an autocomplete option Usually cy.press() for the individual navigation key, then assert the result cy.press(Cypress.Keyboard.Keys.ARROWDOWN)

cy.type() is Cypress’s text-entry command and supports documented special-character and modifier sequences. The cy.type() API reference also points to cy.press() for navigation keys in non-form contexts where more accurate native keyboard simulation is wanted.

5. Runnable keyboard navigation examples

Check Tab order

Start from a known focused element, press Tab, then check the focused target. Repeat the action and assertion for each expected step.

it('moves focus through the form in order', () => {
  cy.visit('/contact')
  cy.get('[data-testid="name"]').focus()
  cy.press(Cypress.Keyboard.Keys.TAB)
  cy.focused().should('have.attr', 'data-testid', 'email')

  cy.press(Cypress.Keyboard.Keys.TAB)
  cy.focused().should('have.attr', 'data-testid', 'message')
})

Check arrow-key navigation

For a menu, listbox, or other widget with custom keyboard behavior, assert the application’s visible or accessible state after sending the key. Adapt the selectors and expected state to the widget’s implementation.

it('moves the active option with the Down Arrow', () => {
  cy.visit('/search')
  cy.get('[role="combobox"]').focus()
  cy.press(Cypress.Keyboard.Keys.ARROWDOWN)
  cy.get('[role="option"][aria-selected="true"]')
    .should('contain.text', 'First result')
})

Check Escape behavior

it('closes a dialog with Escape', () => {
  cy.visit('/settings')
  cy.get('[data-testid="open-dialog"]').click()
  cy.get('[role="dialog"]').should('be.visible')
  cy.press(Cypress.Keyboard.Keys.ESC)
  cy.get('[role="dialog"]').should('not.exist')
})

These examples use Cypress’s normal test runner and assume the page and selectors exist in the application under test. Choose the named-key constant supported by the Cypress version in your project.

6. Keyboard testing and accessibility

Keyboard-only tests can cover focus movement, in-page navigation, and autocomplete behavior. Cypress’s keyboard accessibility guidance discusses these use cases. Build checks around the expected user-visible result: focus location, selected option, expanded state, or whether a dialog closes.

  • Begin from a deterministic state and focus target.
  • Send one key action at a time when the intermediate state matters.
  • Assert the resulting focus or component state after each action.
  • Include a way to reach and operate the control using the keyboard, rather than testing only mouse interactions.

A passing cy.press() call only shows that the command ran. The assertions and broader accessibility checks determine whether the page’s keyboard behavior meets the test’s expectations.

7. Cypress application shortcuts are different

Do not confuse keys dispatched by a test with shortcuts for Cypress’s own interface. Cypress open-mode shortcuts operate the Cypress app: r reruns tests, s stops tests, and f focuses the specs window. When Studio is open and has unsaved changes, its save shortcut is ⌘+s on macOS or Ctrl+s on Windows and Linux.

Those app shortcuts are documented in Cypress keyboard shortcuts. They are not test commands and should not be used as examples of cy.press() behavior.

8. Common errors and fixes

Symptom Likely cause Fix
The test tries to call .should() directly after cy.press() The command yields null. Run a new query such as cy.focused() or query the component’s state, then assert.
A string such as 'hello' is rejected or does not type into the field cy.press() is for a single key, not text entry. Use cy.get('input').type('hello').
A multi-key expression such as {ctrl}c is unsupported It is a cy.type() sequence rather than one cy.press() key. Use the documented cy.type() modifier sequence where appropriate.
A function key does not work F1–F12 are not supported by the current cy.press() API. Use a supported key or another test strategy suited to the behavior being tested.
Focus does not move to the expected control The initial focus, DOM order, disabled state, or app-specific keyboard handling may differ from the assumption. Assert the starting focus, inspect the actual tab order, and check the target’s enabled and visible state.
A key constant is unavailable or behaves differently after an upgrade The installed Cypress version may not provide that key or its supported values may have changed. Check the current API reference and changelog for that version; use a listed Cypress.Keyboard.Keys constant where available.
A custom widget receives a key but its state does not change The application may require focus on a particular element or implement different key behavior. Focus the correct widget element first, then assert the relevant state and review the component’s keyboard handling.

9. Reliability, execution time, and version notes

Keyboard tests are more reliable when they control the starting focus and make an assertion after each meaningful key. Avoid assuming focus order from visual layout alone; the actual DOM order and component behavior determine what the browser focuses. For custom controls, target the element that owns keyboard handling and wait for the application state your test needs before sending the next key.

Use only the key events needed to prove the behavior. Long, repeated sequences can make failures harder to diagnose because the first incorrect transition affects every later assertion. The Cypress changelog records a Chromium renderer-memory fix in 15.19.0 for repeated cy.press() calls; this is a historical release note, not evidence of a current defect.

10. Or skip the browser setup

If you also need screenshots of the page state produced by your tests, ScreenshotNeo can capture a URL in one GET request. It is a website screenshot API and MCP server from ScreenshotNeo. Its clean-shot flow accepts cookie or consent banners like a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each step can be turned off. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, and response headers identify the page verdict and billing status. Its MCP server offers take_screenshot, get_page_info, and capture_pdf for AI agents.

curl -G "https://api.screenshotneo.com/v1/shot" \
  -d access_key=YOUR_API_KEY \
  --data-urlencode url=https://stripe.com \
  -o shot.webp

See the ScreenshotNeo API documentation for request options. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots. Sign up for 1,000 free screenshots a month, with no card required.

11. FAQ

Does cy.press() type into the focused input?

It dispatches a single key event to the browser window; use cy.type() to enter text into a field.

Can cy.press() prove a page is accessible?

No. It lets a test exercise keyboard behavior. Add assertions for the resulting focus and interface state, and assess the page against the accessibility requirements that apply to it.

Are Cypress open-mode shortcuts available inside a test?

They control the Cypress app interface. Use cy.press() for key interactions with the application under test.

Where should I check key support?

Consult the current cy.press() API reference and the changelog for the Cypress version installed in your project.