Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use Cypress’s .clear() command before .type() when the test should replace a field’s current value:

cy.get('input[name="email"]')
  .clear()
  .type('new@example.com')

.type() inserts characters at the field’s current cursor position; it does not automatically replace existing text. If your application can re-render the control between actions, query it again for each action instead of chaining everything from one element reference.

What Cypress does when you call .type()

Cypress models typing at the insertion point. If an input contains old@example.com and the cursor is at the end, .type('new@example.com') appends the new string. If the cursor is in the middle, characters are inserted there. This is different from an assignment such as element.value = ..., which replaces the value without simulating keyboard input.

The documented replacement sequence is therefore two actions: clear the existing value, then type the replacement. Cypress’s migration guidance describes the behavior directly: “.type() behaves the same way, so clear before typing when a field may already contain text.”

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Replace a value with the dependable pattern

Basic text, email, password, and search inputs

Query the control, clear it, type the new value, and assert the resulting value. The assertion makes the test fail at the point where the form state is wrong.

cy.get('input[name="email"]')
  .clear()
  .type('new@example.com')
  .should('have.value', 'new@example.com')

The same pattern works for password and search controls:

cy.get('input[type="password"]').clear().type('correct-horse-battery-staple')
cy.get('input[type="search"]').clear().type('cypress fields')

Keep each action on a fresh query when the DOM can change

Some frameworks replace an input node after focus, validation, masking, or state updates. A chained command can then hold a reference to an element that is no longer the one displayed. Cypress’s retry guidance recommends issuing a new cy.get() before each action in that situation:

cy.get('#payment-input').focus()
cy.get('#payment-input').clear()
cy.get('#payment-input').type('4111111111111111')
cy.get('#payment-input').blur()
cy.get('#payment-input').should('have.value', '4111 1111 1111 1111')

Use the selector that identifies the replacement control consistently. If the application changes the element’s ID or name during re-rendering, use a stable test attribute such as data-cy supplied by the application.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Select all first when keyboard selection is what you are testing

{selectAll} is a special .type() sequence that creates a selection range containing the field’s text. Typing immediately afterward replaces that selection, just as a user might press a select-all shortcut and then enter a value:

cy.get('input[name="email"]')
  .type('{selectAll}')
  .type('new@example.com')
  .should('have.value', 'new@example.com')

This approach is useful when the behavior under test includes selection itself: for example, a custom editor listens for selection events, or you are verifying that a keyboard-oriented workflow preserves the expected cursor semantics. For ordinary form filling, .clear().type() is shorter and communicates the intent more directly.

Choose the approach that matches the test

Situation Recommended commands Reason
Replace whatever is currently in a normal field .clear().type(value) Explicit replacement without depending on cursor location.
Exercise user-style select-all behavior .type('{selectAll}').type(value) Creates a selection range before entering text.
The application may replace the node Fresh cy.get(selector) for each action Each command resolves the current element instead of reusing a stale reference.
Move focus with Tab or send a native single-key event cy.press() Cypress recommends cy.press() for navigation keys and native single-key events.
Rich text editor or managed contenteditable Target the editable host, or use the editor’s API The editor may maintain selection and DOM state outside ordinary input behavior.

Fields that support .type()

Cypress documents typing for textarea, body, focusable elements with a tabindex, elements with contenteditable, and inputs of these types: text, password, email, number, date, week, month, time, datetime-local, search, URL, and telephone.

Native inputs and textareas

For native controls, keep the selector specific and assert the value or the resulting validation state. Date, time, number, and telephone controls can apply browser- or application-specific formatting, so assert the value format your application actually exposes rather than assuming that the typed string is stored unchanged.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
cy.get('input[type="number"]')
  .clear()
  .type('42')
  .should('have.value', '42')

cy.get('textarea[name="message"]')
  .clear()
  .type('A multiline note')
  .should('have.value', 'A multiline note')

Contenteditable and rich editors

When using contenteditable, select the element that owns the contenteditable attribute, not an arbitrary child node inside it:

cy.get('[contenteditable="true"]')
  .clear()
  .type('Updated paragraph')

Editors such as CKEditor, Quill, Draft.js, and ProseMirror can manage selection and DOM updates themselves. Clicking the editor to place the cursor, querying again after each state change, or invoking the editor’s supported API may be necessary. If a visible child receives focus but the host owns the editable state, targeting the child can produce an actionability or value assertion failure.

Focus, actionability, and events

Typing is an action command, so Cypress waits for the subject to become actionable according to its normal rules. The element must be found and able to receive input; hidden, disabled, detached, or covered controls can prevent the command from running. Fix the application state or selector rather than masking a real problem with arbitrary waits.

Cypress fires the keyboard and input events associated with typing. A change event is fired when Enter commits a changed value or when the field loses focus after its value changed. If your application validates on blur, include an explicit blur step and assert the resulting message:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
cy.get('input[name="username"]').clear().type('new-name')
cy.get('input[name="username"]').blur()
cy.get('[data-cy="username-error"]').should('not.exist')

Use .type() for text strings and special sequences such as {selectAll}. For Tab navigation and native single-key events, use cy.press() as recommended by the Cypress API documentation.

Complete test examples

Replacing a prefilled checkout field

describe('checkout contact details', () => {
  it('replaces the saved email address', () => {
    cy.visit('/checkout')
    cy.get('input[name="email"]')
      .clear()
      .type('buyer@example.com')
      .should('have.value', 'buyer@example.com')
    cy.get('button[type="submit"]').click()
  })
})

Testing a keyboard replacement workflow

it('replaces text after selecting all', () => {
  cy.get('[data-cy="promo-code"]')
    .click()
    .type('{selectAll}')
    .type('SPRING25')
    .should('have.value', 'SPRING25')
})

Handling a re-rendering controlled component

it('enters a value into a controlled field', () => {
  cy.get('[data-cy="address-line-1"]').focus()
  cy.get('[data-cy="address-line-1"]').clear()
  cy.get('[data-cy="address-line-1"]').type('1 Main Street')
  cy.get('[data-cy="address-line-1"]').should('have.value', '1 Main Street')
})

Troubleshooting common failures

The new text is appended

Cause: the field still contained text and the cursor was at an insertion point. Fix: use .clear() before typing, or use the {selectAll} sequence when selection is part of the behavior under test.

Cypress says the element is detached

Cause: a framework replaced the DOM node between commands. Fix: split the chain and call cy.get() again before the next action. Prefer a stable selector that survives the component’s render cycle.

.clear() or .type() is not actionable

Cause: the subject may be hidden, covered, disabled, read-only, or no longer attached. Fix: wait for the real UI state through a visible assertion, close the overlay that covers the control, or correct the selector. Do not force the command unless bypassing actionability is itself the behavior being tested.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The value assertion does not match what is displayed

Cause: a mask, formatter, or native date/number control transformed the input. Fix: assert the control’s actual value representation and separately assert any formatted text or validation message shown to the user.

A rich editor receives text in the wrong place

Cause: the editor owns selection and may re-render its internal nodes. Fix: click the editable host to establish the caret, target the host carrying contenteditable, re-query after updates, or use the editor’s documented API for deterministic content changes.

Tab does not behave as expected

Cause: navigation is being expressed as text typing. Fix: use cy.press() for Tab and other native single-key interactions, then assert the newly focused element.

Reliability and maintenance guidance

  • Give each field a stable selector, preferably a dedicated data-cy attribute, so visual redesigns do not silently change the test target.
  • Assert the value immediately after entering it when the value is the behavior under test. This localizes failures and documents the intended result.
  • Use fresh queries only where re-rendering makes them necessary; they add a lookup but avoid stale-element failures. Do not add fixed delays to compensate for an unknown render time.
  • Keep keyboard-selection tests separate from data-entry tests. The former should use {selectAll} and focus assertions; the latter should use the clear-and-type replacement sequence.
  • For controlled components, test both the DOM value and the application outcome, such as a saved record or validation state, because the displayed value can be reformatted.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Or skip the browser setup

If your goal is to capture a page for a test report, visual baseline, or documentation rather than drive a form interaction, ScreenshotNeo returns a website screenshot or PDF from one request. Its API accepts the URL and supports PNG, JPEG, or WebP output; the documentation is at https://screenshotneo.com/docs/.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

cURL

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

Python

import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)

Node.js

const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

Before capture, ScreenshotNeo accepts cookie or consent banners and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each cleanup step can be turned off. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, and each response identifies the page verdict and billing status with X-Page-Verdict and X-Billed headers. An MCP server provides take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients. The Free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots. Other plans are Growth ($15 for 15,000), Pro ($39 for 60,000), Scale ($99 for 250,000), and Business ($249 for 1,000,000); yearly billing gives two months free, and every feature is available on every plan.

Create a free ScreenshotNeo account to get the 1,000 monthly screenshots without adding a card.

Frequently Asked Questions

Does .clear() remove a placeholder?

No. A placeholder is hint text shown when the value is empty; .clear() removes the control’s actual value. Assert have.value when you need to verify the stored text.

Why can a read-only or disabled field not be cleared?

Those states intentionally block editing. Change the application state that makes the control editable, or test the read-only/disabled behavior itself instead of forcing input into it.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

How can I verify that the replacement selected the expected text range?

Use a focused keyboard-flow test with {selectAll}, type a distinctive replacement, and assert both the final value and the focus or selection-related UI state your application exposes.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.