DEV Community

Cover image for My favorite cy.type() tips and tricks
Sam E. Lawrence
Sam E. Lawrence

Posted on • Edited on

My favorite cy.type() tips and tricks

Image description

The problem

Someone in the Cypress Discord faced an issue where cy.type() wouldn't enter the full desired string in a form field, resulting in only a partial string value showing up in the UI (and their test not working as expected). This has happened to me before, and if you work with Cypress long enough, it'll probably happen to you at least once.

This tester's easiest fix was just to insert a hard cy.wait() to ensure that the field was ready for text entry, but we prefer to try to avoid those. There are a few little tricks I use to deal with this issue when it arises, and I use them each in turn depending on the context. Hopefully something here will help you get unstuck if you ever face issues typing text with Cypress.

Example

Here's an example where I'm using all the tricks at once, and I'll break down each one, line by line.

cy.get('field')
  .should('be.visible')
  .clear()
  .type('string', { delay: 0 })
  .should('contain', 'string');
Enter fullscreen mode Exit fullscreen mode

cy.get('field')

No real trick here, but I'll emphasize the importance of selecting the correct element, generally an <input> - though not always guaranteed.

.should('be.visible')

Cypress is much faster than a human. A form field can receive input as soon as it exists in the DOM, but by waiting until it is visible, we have a better chance of waiting long enough for the .type() action to actually take place and have effects like filling the field. In modern apps, there's a lot more stuff being done by Javascript and it's important to be able to wait for element availability as close as possible to their "ready" state. Waiting for visibility (page has been painted) is the first good nudge toward knowing when that "ready" state occurs.

.clear()

Sometimes form fields contain default text that clears based on a click or focus action. If the page's Javascript is still hydrating the page, I've seen this break and newly entered text will sometimes append the placeholder text. It's generally just a good idea to clear the field, unless of course you actually want to append text (as in a "Notes" field).

.type('string', { delay: 0 })

Using { delay: 0 } is open to debate. This option enters the full input string as a chunk, rather than by typing each key individually. This is less like a "real user" would type text into a field, but it can lead to more reliable test automation, if you feel comfortable with the trade-off. It's comparable to a user pasting directly into the field.

.should('contain', 'string');

It's good to check the state of any elements you modify. This command will let us confirm that the field is in the correct state, and we can move on with the rest of our test.

Other options

In my example, I assumed that the field would accept direct text entry, however that's not always the case. You might find that you need to use .click() on the element before you begin typing. You might also want to use .focus() to set your cursor into the field. I didn't include these in my happy-path example, because this post was really just about the .type() command.

A plugin option

If you're using the cypress-real-events plugin, you might choose to use cy.realType() in combination with cy.get().focus(). This command types in each character, just like from a physical keyboard, so this method may be the most "realistic" option, if that is a priority for your testing goals.

I hope this helps

If any of these helped you write more reliable, stable tests - let me know on Twitter, Mastodon, or Bluesky.

Top comments (6)

Collapse
 
vtpetrov profile image
Veselin Petrov

Great write-up, thank you @samelawrence .

Collapse
 
samelawrence profile image
Sam E. Lawrence

Glad you found it helpful!

Collapse
 
andrebelluci profile image
André Augusto Garcia Belluci

Very good tips, when I start with Cypress I find many difficult with cy.type().

Collapse
 
samelawrence profile image
Sam E. Lawrence • Edited

Thank you! It took me a long time to get comfortable with Cypress and years later, I'm still constantly learning new things about how to use it properly. Just keep practicing and using it!

Collapse
 
matonski profile image
Anton de la Fuente

What about adding a {force: true} to type? That has helped me solve this problem even though I don't fully understand why.

Collapse
 
samelawrence profile image
Sam E. Lawrence

Using {force: true} is usually a code smell, but I do have to resort to it as needed. It's nice to know it's an option, for sure!