After querying an element, the next step is interacting with it — clicking buttons, typing into fields, selecting dropdown options, checking checkboxes, and scrolling containers. Cypress action commands are designed to mimic real user behaviour: .type() fires keydown, keypress, keyup and input events exactly as a real keyboard would. .click() moves the mouse, checks the element is visible and not covered, and fires the full click event sequence. This realism catches defects that simpler event-dispatching approaches miss.
Action Commands — Interacting Like a Real User
Each action command performs actionability checks before executing: the element must be visible, not disabled, not covered by another element, and not animating.
// ── Typing and text input ──
// Basic typing
cy.get('#username').type('alice@example.com');
// Type with special keys
cy.get('#search').type('Selenium{enter}'); // Type then press Enter
cy.get('#field').type('{selectall}{backspace}'); // Select all, delete
cy.get('#code').type('{ctrl+a}{ctrl+c}'); // Ctrl+A, Ctrl+C
// Clear and retype
cy.get('#email').clear().type('new@example.com');
// Type slowly (for fields with debounce)
cy.get('#autocomplete').type('Lon', { delay: 100 }); // 100ms between keys
// ── Clicking ──
// Standard click
cy.get('[data-cy="submit"]').click();
// Click at a specific position within the element
cy.get('.map').click('topLeft');
cy.get('.canvas').click(200, 150); // x, y coordinates
// Double-click
cy.get('.editable-cell').dblclick();
// Right-click (context menu)
cy.get('.file-item').rightclick();
// Force click (bypass actionability checks — use sparingly)
cy.get('.hidden-btn').click({ force: true });
// ── Dropdowns and selects ──
// Native HTML
.click(), it verifies the element is visible, not disabled, not covered by another element, not animating, and has non-zero dimensions. If any check fails, Cypress retries until the checks pass or the timeout expires. This is why { force: true } exists — it bypasses these checks for elements that are intentionally hidden or covered (like file inputs styled behind custom upload buttons). Use force: true sparingly and document why it is needed..type('{selectall}{backspace}') instead of .clear() when .clear() does not work on certain React or Angular controlled inputs. Some frameworks do not fire the right events on programmatic clear. The {selectall}{backspace} approach simulates real keyboard actions that trigger all the change detection lifecycle hooks these frameworks rely on.{ force: true } as a default for all clicks. It bypasses actionability checks that exist to catch real UI bugs. If a button is covered by a modal overlay, .click({ force: true }) will click the button but skip the overlay — which real users cannot do. The overlay might be a bug (it should not be there) or expected behaviour (the user needs to dismiss it first). By forcing the click, you mask the defect. Use force only for known, acceptable cases like hidden file inputs.Common Mistakes
Mistake 1 — Using { force: true } to “fix” flaky click failures
❌ Wrong: Every .click() has { force: true } because “it makes the tests pass.”
✅ Correct: Investigating why the click fails — usually an overlay, animation, or disabled state. Fix the root cause (wait for overlay to disappear, wait for animation to finish) instead of forcing.
Mistake 2 — Not using .clear() before .type() on pre-filled fields
❌ Wrong: cy.get('#email').type('new@test.com') on a field that already contains “old@test.com” — result: “old@test.comnew@test.com”.
✅ Correct: cy.get('#email').clear().type('new@test.com') — clear first, then type.