Skip to main content
Cypress App

focus

Focus on a DOM element.

It is unsafe to chain further commands that rely on the subject after .focus().

Syntax​

.focus()
.focus(options)

Usage​

Correct Usage

cy.get('input').first().focus() // Focus on the first input
cy.window().focus() // Focus on the window

Incorrect Usage

cy.focus('#search') // Errors, cannot be chained off 'cy'
cy.get('div:first').focus() // Errors, a plain div is not focusable

Arguments​

options (Object)

Pass in an options object to change the default behavior of .focus().

OptionDefaultDescription
logtrueDisplays the command in the Command log
timeoutdefaultCommandTimeoutTime to wait for .focus() to resolve before timing out

Yields ​

  • .focus() yields the same subject it was given.
  • It is unsafe to chain further commands that rely on the subject after .focus().

Examples​

No Args​

Focus an input and confirm it has focus​

cy.get('input[name="email"]').focus().should('have.focus')

To check which element has focus without a reference to it, use cy.focused().

Focus one element from several matches​

.focus() works on a single element, so narrow the subject first when your selector matches more than one:

cy.get('input').first().focus()
cy.get('button').eq(2).focus()

Focus an element made focusable with tabindex​

Custom widgets such as dialogs and menus often use tabindex to become focusable:

cy.get('[role="dialog"][tabindex="-1"]').focus()

Focus workflows for forms and keyboard testing​

Validate a field when it loses focus​

cy.get('input[name="email"]').focus()
cy.get('input[name="email"]').blur()
cy.get('.error').should('contain', 'Email is required')

You don't need .focus() before .type(), since .type() focuses the element first. Reach for .focus() when you need focus without typing.

Open UI that appears on focus​

cy.get('input[name="search"]').focus()
cy.get('[role="listbox"]').should('be.visible')

Test keyboard tab order​

Set the starting point with .focus(), move focus with cy.press(), and check where it went with cy.focused():

cy.get('input[name="first-name"]').focus()
cy.press(Cypress.Keyboard.Keys.TAB)
cy.focused().should('have.attr', 'name', 'last-name')

Notes​

Actionability​

Focus is not an action command​

.focus() is not implemented like other action commands, and does not follow the same rules of waiting for actionability.

.focus() is a helpful command used as a shortcut. Normally there's no way for a user to "focus" an element without causing another action or side effect. Typically the user would have to click or tab to this element.

Oftentimes using .focus() directly is more concise and conveys what you're trying to test.

If you want the other guarantees of waiting for an element to become actionable, you should use a different command like .click().

Blur Events​

Cypress blurs other focused elements first​

If there is currently a different DOM element with focus, Cypress issues a blur event to that element before running the .focus() command.

Focusable​

Can only be called on a valid focusable element​

Cypress treats these elements as focusable:

  • a and area elements with an href
  • input, select, textarea, and button elements that aren't disabled
  • iframe elements
  • Any element with a tabindex or contenteditable attribute

Calling .focus() on anything else fails with an error. The window and the body are the two exceptions:

  • cy.window().focus() fires a focus event on the window. Focus itself does not move: whichever element held it still does, and document.activeElement is unchanged.
  • cy.get('body').focus() passes without error but fires no events, since the body doesn't receive focus. The exception is a contenteditable body, which Cypress focuses like any other element.

Rules​

Requirements ​

  • .focus() requires being chained off a command that yields a DOM element or the window.
  • .focus() requires the subject to contain a single element.
  • .focus() requires the element to be able to receive focus. The window and the body are exempt.

Assertions ​

  • .focus() will automatically wait for assertions you have chained to pass.

Timeouts ​

  • .focus() can time out waiting for assertions you've added to pass.

Command Log​

Focus the textarea

cy.get('[name="comment"]').focus()

The commands above will display in the Command Log as:

Command Log showing the get command followed by the focus command

When clicking on the focus command within the command log, the console outputs the following:

Browser console showing the textarea that .focus() was applied to

See also​