| title | type |
|---|
Type into a DOM element.
.type(text)
.type(text, options){% fa fa-check-circle green %} Correct Usage
cy.get('input').type('Hello, World') // Type 'Hello, World' into the 'input'{% fa fa-exclamation-triangle red %} Incorrect Usage
cy.type('Welcome') // Errors, cannot be chained off 'cy'
cy.url().type('www.cypress.io') // Errors, 'url' does not yield DOM element{% fa fa-angle-right %} text (String)
The text to be typed into the DOM element.
Text passed to .type() may include any of the special character sequences below.
{% note info %}
To disable parsing special characters sequences, set the parseSpecialCharSequences option to false.
{% endnote %}
| Sequence | Notes |
|---|---|
{% raw %}{{{% endraw %}} |
Types the literal { key |
{backspace} |
Deletes character to the left of the cursor |
{del} |
Deletes character to the right of the cursor |
{downarrow} |
Moves cursor down |
{end} |
Moves cursor to the end of the line |
{enter} |
Types the Enter key |
{esc} |
Types the Escape key |
{home} |
Moves cursor to the start of the line |
{insert} |
Inserts character to the right of the cursor |
{leftarrow} |
Moves cursor left |
{pagedown} |
Scrolls down |
{pageup} |
Scrolls up |
{rightarrow} |
Moves cursor right |
{selectall} |
Selects all text by creating a selection range |
{uparrow} |
Moves cursor up |
Text passed to .type() may also include any of these modifier character sequences:
| Sequence | Notes |
|---|---|
{alt} |
Activates the altKey modifier. Aliases: {option} |
{ctrl} |
Activates the ctrlKey modifier. Aliases: {control} |
{meta} |
Activates the metaKey modifier. Aliases: {command}, {cmd} |
{shift} |
Activates the shiftKey modifier. |
{% fa fa-angle-right %} options (Object)
Pass in an options object to change the default behavior of .type().
| Option | Default | Description |
|---|---|---|
log |
true |
{% usage_options log %} |
delay |
10 |
Delay after each keypress |
force |
false |
{% usage_options force type %} |
parseSpecialCharSequences |
true |
Parse special characters for strings surrounded by {}, such as {esc}. Set to false to type the literal characters instead |
release |
true |
Keep a modifier activated between commands |
timeout |
{% url defaultCommandTimeout configuration#Timeouts %} |
{% usage_options timeout .type %} |
{% yields same_subject .type %}
cy.get('textarea').type('Hello world') // yields <textarea>{% note info %} {% url "Check out our example recipe of logging in by typing username and password in HTML web forms" recipes#Logging-In %} {% endnote %}
Each keypress is delayed 10ms by default in order to simulate how a very fast user types!
cy.get('[contenteditable]').type('some text!')For 'selecting' an option, just type it into the input.
<input list="fruit" />
<datalist id="fruit">
<option>Apple</option>
<option>Banana</option>
<option>Cantaloupe</option>
</datalist>cy.get('input').type('Apple')<body>
<div id="el" tabindex="1">
This div can receive focus!
</div>
</body>cy.get('#el').type('supercalifragilisticexpialidocious')Using .type() on a date input (<input type="date">) requires specifying a valid date in the format:
yyyy-MM-dd(e.g.1999-12-31)
This isn't exactly how a user would type into a date input, but is a workaround since date input support varies between browsers and the format varies based on locale. yyyy-MM-dd is the format required by {% url "the W3 spec" https://www.w3.org/TR/html/infrastructure.html#dates-and-times %} and is what the input's value will be set to regardless of browser or locale.
Special characters ({leftarrow}, {selectall}, etc.) are not permitted.
Using .type() on a month input (<input type="month">) requires specifying a valid month in the format:
yyyy-MM(e.g.1999-12)
This isn't exactly how a user would type into a month input, but is a workaround since month input support varies between browsers and the format varies based on locale. yyyy-MM is the format required by {% url "the W3 spec" https://www.w3.org/TR/html/infrastructure.html#months %} and is what the input's value will be set to regardless of browser or locale.
Special characters ({leftarrow}, {selectall}, etc.) are not permitted.
Using .type() on a week input (<input type="week">) requires specifying a valid week in the format:
yyyy-Www(e.g.1999-W23)
Where W is the literal character 'W' and ww is the number of the week (01-53).
This isn't exactly how a user would type into a week input, but is a workaround since week input support varies between browsers and the format varies based on locale. yyyy-Www is the format required by {% url "the W3 spec" https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#valid-week-string %} and is what the input's value will be set to regardless of browser or locale.
Special characters ({leftarrow}, {selectall}, etc.) are not permitted.
Using .type() on a time input (<input type="time">) requires specifying a valid time in the format:
HH:mm(e.g.01:30or23:15)HH:mm:ss(e.g.10:00:30)HH:mm:ss.SSS(e.g.12:00:00.384)
Where HH is 00-23, mm is 00-59, ss is 00-59, and SSS is 000-999.
Special characters ({leftarrow}, {selectall}, etc.) are not permitted.
When using special character sequences, it's possible to activate modifier keys and type key combinations, such as CTRL + R or SHIFT + ALT + Q. The modifier(s) remain activated for the duration of the .type() command, and are released when all subsequent characters are typed, unless {% url '{release: false}' type#Options %} is passed as an {% url 'option' type#Key-Combinations %}. A keydown event is fired when a modifier is activated and a keyup event is fired when it is released.
// this is the same as a user holding down SHIFT and ALT, then pressing Q
cy.get('input').type('{shift}{alt}Q')To disable parsing special characters sequences, set the parseSpecialCharSequences option to false.
cy.get('#code-input')
// will not escape { } characters
.type('function (num) {return num * num;}', { parseSpecialCharSequences: false })// all characters after {ctrl} will have 'ctrlKey'
// set to 'true' on their key events
cy.get('input').type('{ctrl}test')By default, modifiers are released after each type command.
// 'ctrlKey' will be true for each event while 'test' is typed
// but false while 'everything' is typed
cy.get('input').type('{ctrl}test').type('everything')To keep a modifier activated between commands, specify {release: false} in the options.
// 'altKey' will be true while typing 'foo'
cy.get('input').type('{alt}foo', { release: false })
// 'altKey' will also be true during 'get' and 'click' commands
cy.get('button').click()Modifiers are automatically released between tests, even with {release: false}.
it('has modifiers activated', function () {
// 'altKey' will be true while typing 'foo'
cy.get('input').type('{alt}foo', { release: false })
})
it('does not have modifiers activated', function () {
// 'altKey' will be false while typing 'bar'
cy.get('input').type('bar')
})To manually release modifiers within a test after using {release: false}, use another type command and the modifier will be released after it.
// 'altKey' will be true while typing 'foo'
cy.get('input').type('{alt}foo', { release: false })
// 'altKey' will be true during the 'get' and 'click' commands
cy.get('button').click()
// 'altKey' will be released after this command
cy.get('input').type('{alt}')
// 'altKey' will be false during the 'get' and 'click' commands
cy.get('button').click().type() requires a focusable element as the subject, since it's usually intended to type into something that's an input or textarea. Although there are a few cases where it's valid to "type" into something other than an input or textarea:
- Keyboard shortcuts where the listener is on the
documentorbody. - Holding modifier keys and clicking an arbitrary element.
To support this, the body can be used as the DOM element to type into (even though it's not a focusable element).
// all of the type events are fired on the body
cy.get('body').type('{uparrow}{uparrow}{downarrow}{downarrow}{leftarrow}{rightarrow}{leftarrow}{rightarrow}ba')// execute a SHIFT + click on the first <li>
// {release: false} is necessary so that
// SHIFT will not be released after the type command
cy.get('body').type('{shift}', { release: false }).get('li:first').click()Forcing typing overrides the {% url 'actionable checks' interacting-with-elements#Forcing %} Cypress applies and will automatically fire the events.
cy.get('input[type=text]').type('Test all the things', { force: true })- ^HTML
<body>and<textarea>elements. - Elements with a defined
tabindexattribute. - Elements with a defined
contenteditableattribute. - ^HTML
<input>elements with a definedtypeattribute of one of the following:textpasswordemailnumberdateweekmonthtimedatetime-localsearchurltel
.type() is an "action command" that follows all the rules {% url 'defined here' interacting-with-elements %}.
If the element is currently not in focus, before issuing any keystrokes Cypress will first issue a {% url .click() click %} to the element to bring it into focus.
Once the element is in focus, Cypress will begin firing keyboard events.
The following events will be fired based on what key was pressed identical to the event spec:
keydownkeypresstextInputinputkeyup
beforeinput is not fired even though it is in the spec because no browser has adopted it.
Additionally change events will be fired either when the {enter} key is pressed (and the value has changed since the last focus event), or whenever the element loses focus. This matches browser behavior.
Events that should not fire on non input types such as elements with tabindex do not fire their textInput or input events. Only typing into elements which cause the actual value or text to change will fire those events.
The following rules have been implemented that match real browser behavior (and the spec):
- Cypress respects not firing subsequent events if previous ones were canceled.
- Cypress will fire
keypressonly if that key is supposed to actually firekeypress. - Cypress will fire
textInputonly if typing that key would have inserted an actual character. - Cypress will fire
inputonly if typing that key modifies or changes the value of the element.
Cypress respects all default browser behavior when events are canceled.
// prevent the characters from being inserted
// by canceling keydown, keypress, or textInput
$('#username').on('keydown', (e) => {
e.preventDefault()
})
// Cypress will not insert any characters if keydown, keypress, or textInput
// are cancelled - which matches the default browser behavior
cy.get('#username').type('bob@gmail.com').should('have.value', '') // trueIn a real browser, preventing mousedown on a form field will prevent it from receiving focus and thus prevent it from being able to be typed into. Currently, Cypress does not factor this in. {% open_an_issue %} if you need this to be fixed.
Cypress prints out a table of key events that detail the keys that were pressed when clicking on type within the {% urlHash 'Command Log' Command-Log %}. Each character will contain the which character code and the events that happened as a result of that key press.
Events that were defaultPrevented may prevent other events from firing and those will show up as empty. For instance, canceling keydown will not fire keypress or textInput or input, but will fire keyup (which matches the spec).
Additionally, events that cause a change event to fire (such as typing {enter}) will display with the change event column as true.
Any modifiers activated for the event are also listed in a modifiers column.
{% imgTag /img/api/type/key-events-table-shown-in-console-for-testing-typing.png "Cypress .type() key events table" %}
Tabbing will be implemented as part of our work on {% issue 311 "Native Browser Events" %} and will support things like multiple tabs, tabbing in reverse, or tabbing to a specific element.
In the meantime, you can use the experimental {% url "cypress-plugin-tab" https://github.com/Bkucera/cypress-plugin-tab %} and can thumbs up {% issue 299 "this issue" %}.
In a real browser, if a user holds SHIFT and types a, a capital A will be typed into the input. Currently, Cypress does not simulate that behavior.
Modifiers are simulated by setting their corresponding values to true for key and click events. So, for example, activating the {shift} modifier will set event.shiftKey to true for any key events, such as keydown.
// app code
document.querySelector('input:first').addEventListener('keydown', (e) => {
// e.shiftKey will be true
})
// in test
cy.get('input:first').type('{shift}a')In the example above, a lowercase a will be typed, because that's the literal character specified. To type a capital A, you can use .type('{shift}A') (or .type('A') if you don't care about the shiftKey property on any key events).
This holds true for other special key combinations as well (that may be OS-specific). For example, on OSX, typing ALT + SHIFT + K creates the special character . Like with capitalization, .type() will not output , but the letter k. {% open_an_issue %} if you need modifier effects to be implemented.
Cypress automatically matches the spec and browser behavior for pressing the {enter} key when the input belongs to a <form>.
This behavior is defined here: {% url "Form Implicit Submission" https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#implicit-submission %}.
For instance the following will submit the form.
<form action="/login">
<input id="username" />
<input id="password" />
<button type="submit">Log In</button>
</form>cy.get('#username').type('bob@burgers.com')
cy.get('#password').type('password123{enter}')Because there are multiple inputs and one submit button, Cypress submits the form (and fires submit events) as well as a synthetic click event to the button.
The spec defines the "submit" button as the first input[type=submit] or button[type!=button] from the form.
Additionally Cypress handles these 4 other situations as defined in the spec:
- Does not submit a form if there are multiple inputs and no
submitbutton. - Does not submit a form if the
submitbutton is disabled. - Submits a form, but does not fire synthetic
clickevent, if there is 1inputand nosubmitbutton - Submits form and fires a synthetic
clickevent to thesubmitwhen it exists.
If the form's submit event is preventedDefault the form will not actually be submitted.
{% requirements dom .type %}
{% assertions actions .type %}
{% timeouts actions .type %}
Type into the input
cy.get('input[name=firstName]').type('Jane Lane')The commands above will display in the Command Log as:
{% imgTag /img/api/type/type-in-input-shown-in-command-log.png "Command Log type" %}
When clicking on type within the command log, the console outputs the following:
{% imgTag /img/api/type/console-log-of-typing-with-entire-key-events-table-for-each-character.png "Console Log type" %}
{% history %}
{% url "3.4.1" changelog#3-4-1 %} | Added parseSpecialCharSequences option
{% url "3.3.0" changelog#3-3-0 %} | Added {insert}, {pageup} and {pagedown} character sequences
{% url "3.2.0" changelog#3-2-0 %} | Added {home} and {end} character sequences
{% url "0.20.0" changelog#0-20-0 %} | Supports for typing in inputs of type date, time, month, and week
{% url "0.17.1" changelog#0-17-1 %} | Added ctrl, cmd, shift, and alt keyboard modifiers
{% url "0.16.3" changelog#0-16-3 %} | Supports for typing in elements with tabindex attribute
{% url "0.16.2" changelog#0-16-2 %} | Added {downarrow} and {uparrow} character sequences
{% url "0.8.0" changelog#0-8-0 %} | Outputs Key Events Table to console on click
{% url "0.8.0" changelog#0-8-0 %} | Added {selectall}, {del}, {backspace}, {esc}, {% raw %}{{{% endraw %}}, {enter}, {leftarrow}, {rightarrow} character sequences
{% url "0.8.0" changelog#0-8-0 %} | Added small delay (10ms) between each keystroke during cy.type()
{% url "0.6.12" changelog#0-6-12 %} | Added option force
{% endhistory %}
- {% url
.blur()blur %} - {% url
.clear()clear %} - {% url
.click()click %} - {% url
.focus()focus %} - {% url
.submit()submit %}