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');
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.
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.